From 66ee4f59d6fdf5e1617ca5d1191155eeed3ccf58 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 13:34:51 +0000 Subject: [PATCH 01/25] Replace JSONC plugin with C concrete-syntax parser foundation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert this package from @jsonic/jsonc to @jsonic/c. Targets C23 with GCC/Clang/MSVC extensions; produces a concrete syntax tree preserving every token, comment, macro, and extension as-is. - src/tokens.ts: token catalog covering C23 keywords, all extension keywords, every punctuator (one named token per literal form). - src/symbols.ts: SymbolTable with full nested scopes (file, fn-proto, fn-body, block, struct-union, enum, for-init), MacroTable, and a LexMode flag bag — all bundled as CMeta on ctx.meta.cmeta so lex matchers and rule actions share the same state. - src/matchers.ts: focused lex matchers, one job each — whitespace, line continuation, line/block comments, preprocessor directive opener (line-start gated), directive newline, header name (mode-gated), identifier with keyword/typedef-name/macro-name reclassification, integer (dec/hex/oct/binary, separators, suffixes), float (decimal + hex), char (with prefixes), string (with prefixes and raw R""), and a single longest-match punctuator dispatch. - src/c.ts: plugin entry. Disables jsonic's built-in lexers so our matchers fully own tokenization, registers all token names so grammar rules can reference them, installs CMeta via parse.prepare. Grammar covers translation_unit -> extdecl_loop -> external_declaration with a coarse-grained token chomper that recognises the typedef-name shape and registers it in the symbol table. Pre-lexed lookahead tokens are reclassified in place after typedef registration so subsequent matches see TYPEDEF_NAME immediately. Smoke tests cover tokenization correctness (keyword vs identifier boundary, multi-char punctuator dispatch, comment trivia preservation) and the typedef disambiguation path end to end. Subsequent slices will replace the chomper with proper declarator, declaration, statement, and expression grammar (the latter driven by @jsonic/expr); add directive nodes via @jsonic/directive with best-effort parsing of conditional groups; and surface the macro table to tag macro-call sites. --- Makefile | 48 +- README.md | 297 ++------ THIRD_PARTY_NOTICES.md | 50 -- embed-grammar.js | 74 -- go/go.mod | 5 - go/go.sum | 2 - go/jsonc.go | 82 --- go/jsonc_test.go | 634 ------------------ jsonc-grammar.jsonic | 34 - package.json | 31 +- src/c.ts | 307 +++++++++ src/jsonc.ts | 71 -- src/matchers.ts | 508 ++++++++++++++ src/symbols.ts | 165 +++++ src/tokens.ts | 201 ++++++ test/JSONTestSuite/LICENSE | 21 - test/JSONTestSuite/README.md | 55 -- .../i_number_double_huge_neg_exp.json | 1 - .../test_parsing/i_number_huge_exp.json | 1 - .../i_number_neg_int_huge_exp.json | 1 - .../i_number_pos_double_huge_exp.json | 1 - .../i_number_real_neg_overflow.json | 1 - .../i_number_real_pos_overflow.json | 1 - .../test_parsing/i_number_real_underflow.json | 1 - .../i_number_too_big_neg_int.json | 1 - .../i_number_too_big_pos_int.json | 1 - .../i_number_very_big_negative_int.json | 1 - .../i_object_key_lone_2nd_surrogate.json | 1 - ..._string_1st_surrogate_but_2nd_missing.json | 1 - ...tring_1st_valid_surrogate_2nd_invalid.json | 1 - .../i_string_UTF-16LE_with_BOM.json | Bin 12 -> 0 bytes .../i_string_UTF-8_invalid_sequence.json | 1 - .../i_string_UTF8_surrogate_U+D800.json | 1 - ...incomplete_surrogate_and_escape_valid.json | 1 - .../i_string_incomplete_surrogate_pair.json | 1 - ...ng_incomplete_surrogates_escape_valid.json | 1 - .../i_string_invalid_lonely_surrogate.json | 1 - .../i_string_invalid_surrogate.json | 1 - .../test_parsing/i_string_invalid_utf-8.json | 1 - .../i_string_inverted_surrogates_U+1D11E.json | 1 - .../test_parsing/i_string_iso_latin_1.json | 1 - .../i_string_lone_second_surrogate.json | 1 - .../i_string_lone_utf8_continuation_byte.json | 1 - .../i_string_not_in_unicode_range.json | 1 - .../i_string_overlong_sequence_2_bytes.json | 1 - .../i_string_overlong_sequence_6_bytes.json | 1 - ...string_overlong_sequence_6_bytes_null.json | 1 - .../i_string_truncated-utf-8.json | 1 - .../test_parsing/i_string_utf16BE_no_BOM.json | Bin 10 -> 0 bytes .../test_parsing/i_string_utf16LE_no_BOM.json | Bin 10 -> 0 bytes .../i_structure_500_nested_arrays.json | 1 - .../i_structure_UTF-8_BOM_empty_object.json | 1 - .../n_array_1_true_without_comma.json | 1 - .../test_parsing/n_array_a_invalid_utf8.json | 1 - .../n_array_colon_instead_of_comma.json | 1 - .../n_array_comma_after_close.json | 1 - .../n_array_comma_and_number.json | 1 - .../test_parsing/n_array_double_comma.json | 1 - .../n_array_double_extra_comma.json | 1 - .../test_parsing/n_array_extra_close.json | 1 - .../test_parsing/n_array_extra_comma.json | 1 - .../test_parsing/n_array_incomplete.json | 1 - .../n_array_incomplete_invalid_value.json | 1 - .../n_array_inner_array_no_comma.json | 1 - .../test_parsing/n_array_invalid_utf8.json | 1 - .../n_array_items_separated_by_semicolon.json | 1 - .../test_parsing/n_array_just_comma.json | 1 - .../test_parsing/n_array_just_minus.json | 1 - .../test_parsing/n_array_missing_value.json | 1 - .../n_array_newlines_unclosed.json | 3 - .../n_array_number_and_comma.json | 1 - .../n_array_number_and_several_commas.json | 1 - .../n_array_spaces_vertical_tab_formfeed.json | 1 - .../test_parsing/n_array_star_inside.json | 1 - .../test_parsing/n_array_unclosed.json | 1 - .../n_array_unclosed_trailing_comma.json | 1 - .../n_array_unclosed_with_new_lines.json | 3 - .../n_array_unclosed_with_object_inside.json | 1 - .../test_parsing/n_incomplete_false.json | 1 - .../test_parsing/n_incomplete_null.json | 1 - .../test_parsing/n_incomplete_true.json | 1 - .../n_multidigit_number_then_00.json | Bin 4 -> 0 bytes .../test_parsing/n_number_++.json | 1 - .../test_parsing/n_number_+1.json | 1 - .../test_parsing/n_number_+Inf.json | 1 - .../test_parsing/n_number_-01.json | 1 - .../test_parsing/n_number_-1.0..json | 1 - .../test_parsing/n_number_-2..json | 1 - .../test_parsing/n_number_-NaN.json | 1 - .../test_parsing/n_number_.-1.json | 1 - .../test_parsing/n_number_.2e-3.json | 1 - .../test_parsing/n_number_0.1.2.json | 1 - .../test_parsing/n_number_0.3e+.json | 1 - .../test_parsing/n_number_0.3e.json | 1 - .../test_parsing/n_number_0.e1.json | 1 - .../test_parsing/n_number_0_capital_E+.json | 1 - .../test_parsing/n_number_0_capital_E.json | 1 - .../test_parsing/n_number_0e+.json | 1 - .../test_parsing/n_number_0e.json | 1 - .../test_parsing/n_number_1.0e+.json | 1 - .../test_parsing/n_number_1.0e-.json | 1 - .../test_parsing/n_number_1.0e.json | 1 - .../test_parsing/n_number_1_000.json | 1 - .../test_parsing/n_number_1eE2.json | 1 - .../test_parsing/n_number_2.e+3.json | 1 - .../test_parsing/n_number_2.e-3.json | 1 - .../test_parsing/n_number_2.e3.json | 1 - .../test_parsing/n_number_9.e+.json | 1 - .../test_parsing/n_number_Inf.json | 1 - .../test_parsing/n_number_NaN.json | 1 - .../n_number_U+FF11_fullwidth_digit_one.json | 1 - .../test_parsing/n_number_expression.json | 1 - .../test_parsing/n_number_hex_1_digit.json | 1 - .../test_parsing/n_number_hex_2_digits.json | 1 - .../test_parsing/n_number_infinity.json | 1 - .../test_parsing/n_number_invalid+-.json | 1 - .../n_number_invalid-negative-real.json | 1 - .../n_number_invalid-utf-8-in-bigger-int.json | 1 - .../n_number_invalid-utf-8-in-exponent.json | 1 - .../n_number_invalid-utf-8-in-int.json | 1 - .../test_parsing/n_number_minus_infinity.json | 1 - ...mber_minus_sign_with_trailing_garbage.json | 1 - .../test_parsing/n_number_minus_space_1.json | 1 - .../n_number_neg_int_starting_with_zero.json | 1 - .../n_number_neg_real_without_int_part.json | 1 - .../n_number_neg_with_garbage_at_end.json | 1 - .../n_number_real_garbage_after_e.json | 1 - ...number_real_with_invalid_utf8_after_e.json | 1 - ...n_number_real_without_fractional_part.json | 1 - .../n_number_starting_with_dot.json | 1 - .../test_parsing/n_number_with_alpha.json | 1 - .../n_number_with_alpha_char.json | 1 - .../n_number_with_leading_zero.json | 1 - .../test_parsing/n_object_bad_value.json | 1 - .../test_parsing/n_object_bracket_key.json | 1 - .../n_object_comma_instead_of_colon.json | 1 - .../test_parsing/n_object_double_colon.json | 1 - .../test_parsing/n_object_emoji.json | 1 - .../test_parsing/n_object_garbage_at_end.json | 1 - .../n_object_key_with_single_quotes.json | 1 - ...uation_byte_in_key_and_trailing_comma.json | 1 - .../test_parsing/n_object_missing_colon.json | 1 - .../test_parsing/n_object_missing_key.json | 1 - .../n_object_missing_semicolon.json | 1 - .../test_parsing/n_object_missing_value.json | 1 - .../test_parsing/n_object_no-colon.json | 1 - .../test_parsing/n_object_non_string_key.json | 1 - ...on_string_key_but_huge_number_instead.json | 1 - .../n_object_repeated_null_null.json | 1 - .../n_object_several_trailing_commas.json | 1 - .../test_parsing/n_object_single_quote.json | 1 - .../test_parsing/n_object_trailing_comma.json | 1 - .../n_object_trailing_comment.json | 1 - .../n_object_trailing_comment_open.json | 1 - .../n_object_trailing_comment_slash_open.json | 1 - ...railing_comment_slash_open_incomplete.json | 1 - .../n_object_two_commas_in_a_row.json | 1 - .../test_parsing/n_object_unquoted_key.json | 1 - .../n_object_unterminated-value.json | 1 - .../n_object_with_single_string.json | 1 - .../n_object_with_trailing_garbage.json | 1 - .../test_parsing/n_single_space.json | 1 - .../n_string_1_surrogate_then_escape.json | 1 - .../n_string_1_surrogate_then_escape_u.json | 1 - .../n_string_1_surrogate_then_escape_u1.json | 1 - .../n_string_1_surrogate_then_escape_u1x.json | 1 - .../n_string_accentuated_char_no_quotes.json | 1 - .../test_parsing/n_string_backslash_00.json | Bin 6 -> 0 bytes .../test_parsing/n_string_escape_x.json | 1 - .../n_string_escaped_backslash_bad.json | 1 - .../n_string_escaped_ctrl_char_tab.json | 1 - .../test_parsing/n_string_escaped_emoji.json | 1 - .../n_string_incomplete_escape.json | 1 - ...n_string_incomplete_escaped_character.json | 1 - .../n_string_incomplete_surrogate.json | 1 - ...g_incomplete_surrogate_escape_invalid.json | 1 - .../n_string_invalid-utf-8-in-escape.json | 1 - .../n_string_invalid_backslash_esc.json | 1 - .../n_string_invalid_unicode_escape.json | 1 - .../n_string_invalid_utf8_after_escape.json | 1 - .../n_string_leading_uescaped_thinspace.json | 1 - .../n_string_no_quotes_with_bad_escape.json | 1 - .../n_string_single_doublequote.json | 1 - .../test_parsing/n_string_single_quote.json | 1 - ...string_single_string_no_double_quotes.json | 1 - .../n_string_start_escape_unclosed.json | 1 - .../n_string_unescaped_ctrl_char.json | Bin 7 -> 0 bytes .../n_string_unescaped_newline.json | 2 - .../test_parsing/n_string_unescaped_tab.json | 1 - .../n_string_unicode_CapitalU.json | 1 - .../n_string_with_trailing_garbage.json | 1 - .../n_structure_100000_opening_arrays.json | 1 - .../n_structure_U+2060_word_joined.json | 1 - .../n_structure_UTF8_BOM_no_data.json | 1 - .../n_structure_angle_bracket_..json | 1 - .../n_structure_angle_bracket_null.json | 1 - .../n_structure_array_trailing_garbage.json | 1 - ...tructure_array_with_extra_array_close.json | 1 - ..._structure_array_with_unclosed_string.json | 1 - .../n_structure_ascii-unicode-identifier.json | 1 - .../n_structure_capitalized_True.json | 1 - .../n_structure_close_unopened_array.json | 1 - ...ucture_comma_instead_of_closing_brace.json | 1 - .../n_structure_double_array.json | 1 - .../test_parsing/n_structure_end_array.json | 1 - .../n_structure_incomplete_UTF8_BOM.json | 1 - .../n_structure_lone-invalid-utf-8.json | 1 - .../n_structure_lone-open-bracket.json | 1 - .../test_parsing/n_structure_no_data.json | 0 .../n_structure_null-byte-outside-string.json | Bin 3 -> 0 bytes ...tructure_number_with_trailing_garbage.json | 1 - ...ure_object_followed_by_closing_object.json | 1 - .../n_structure_object_unclosed_no_value.json | 1 - .../n_structure_object_with_comment.json | 1 - ...tructure_object_with_trailing_garbage.json | 1 - .../n_structure_open_array_apostrophe.json | 1 - .../n_structure_open_array_comma.json | 1 - .../n_structure_open_array_object.json | 1 - .../n_structure_open_array_open_object.json | 1 - .../n_structure_open_array_open_string.json | 1 - .../n_structure_open_array_string.json | 1 - .../test_parsing/n_structure_open_object.json | 1 - .../n_structure_open_object_close_array.json | 1 - .../n_structure_open_object_comma.json | 1 - .../n_structure_open_object_open_array.json | 1 - .../n_structure_open_object_open_string.json | 1 - ...e_open_object_string_with_apostrophes.json | 1 - .../test_parsing/n_structure_open_open.json | 1 - .../n_structure_single_eacute.json | 1 - .../test_parsing/n_structure_single_star.json | 1 - .../test_parsing/n_structure_trailing_#.json | 1 - ...n_structure_uescaped_LF_before_string.json | 1 - .../n_structure_unclosed_array.json | 1 - ...structure_unclosed_array_partial_null.json | 1 - ...cture_unclosed_array_unfinished_false.json | 1 - ...ucture_unclosed_array_unfinished_true.json | 1 - .../n_structure_unclosed_object.json | 1 - .../n_structure_unicode-identifier.json | 1 - ...ructure_whitespace_U+2060_word_joiner.json | 1 - .../n_structure_whitespace_formfeed.json | 1 - .../y_array_arraysWithSpaces.json | 1 - .../test_parsing/y_array_empty-string.json | 1 - .../test_parsing/y_array_empty.json | 1 - .../y_array_ending_with_newline.json | 1 - .../test_parsing/y_array_false.json | 1 - .../test_parsing/y_array_heterogeneous.json | 1 - .../test_parsing/y_array_null.json | 1 - .../y_array_with_1_and_newline.json | 2 - .../y_array_with_leading_space.json | 1 - .../y_array_with_several_null.json | 1 - .../y_array_with_trailing_space.json | 1 - test/JSONTestSuite/test_parsing/y_number.json | 1 - .../test_parsing/y_number_0e+1.json | 1 - .../test_parsing/y_number_0e1.json | 1 - .../test_parsing/y_number_after_space.json | 1 - .../y_number_double_close_to_zero.json | 1 - .../test_parsing/y_number_int_with_exp.json | 1 - .../test_parsing/y_number_minus_zero.json | 1 - .../test_parsing/y_number_negative_int.json | 1 - .../test_parsing/y_number_negative_one.json | 1 - .../test_parsing/y_number_negative_zero.json | 1 - .../test_parsing/y_number_real_capital_e.json | 1 - .../y_number_real_capital_e_neg_exp.json | 1 - .../y_number_real_capital_e_pos_exp.json | 1 - .../test_parsing/y_number_real_exponent.json | 1 - .../y_number_real_fraction_exponent.json | 1 - .../test_parsing/y_number_real_neg_exp.json | 1 - .../y_number_real_pos_exponent.json | 1 - .../test_parsing/y_number_simple_int.json | 1 - .../test_parsing/y_number_simple_real.json | 1 - test/JSONTestSuite/test_parsing/y_object.json | 1 - .../test_parsing/y_object_basic.json | 1 - .../test_parsing/y_object_duplicated_key.json | 1 - .../y_object_duplicated_key_and_value.json | 1 - .../test_parsing/y_object_empty.json | 1 - .../test_parsing/y_object_empty_key.json | 1 - .../y_object_escaped_null_in_key.json | 1 - .../y_object_extreme_numbers.json | 1 - .../test_parsing/y_object_long_strings.json | 1 - .../test_parsing/y_object_simple.json | 1 - .../test_parsing/y_object_string_unicode.json | 1 - .../test_parsing/y_object_with_newlines.json | 3 - .../y_string_1_2_3_bytes_UTF-8_sequences.json | 1 - .../y_string_accepted_surrogate_pair.json | 1 - .../y_string_accepted_surrogate_pairs.json | 1 - .../y_string_allowed_escapes.json | 1 - ...y_string_backslash_and_u_escaped_zero.json | 1 - .../y_string_backslash_doublequotes.json | 1 - .../test_parsing/y_string_comments.json | 1 - .../y_string_double_escape_a.json | 1 - .../y_string_double_escape_n.json | 1 - .../y_string_escaped_control_character.json | 1 - .../y_string_escaped_noncharacter.json | 1 - .../test_parsing/y_string_in_array.json | 1 - .../y_string_in_array_with_leading_space.json | 1 - .../y_string_last_surrogates_1_and_2.json | 1 - .../test_parsing/y_string_nbsp_uescaped.json | 1 - ...y_string_nonCharacterInUTF-8_U+10FFFF.json | 1 - .../y_string_nonCharacterInUTF-8_U+FFFF.json | 1 - .../test_parsing/y_string_null_escape.json | 1 - .../test_parsing/y_string_one-byte-utf-8.json | 1 - .../test_parsing/y_string_pi.json | 1 - ...ring_reservedCharacterInUTF-8_U+1BFFF.json | 1 - .../test_parsing/y_string_simple_ascii.json | 1 - .../test_parsing/y_string_space.json | 1 - ...rogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json | 1 - .../y_string_three-byte-utf-8.json | 1 - .../test_parsing/y_string_two-byte-utf-8.json | 1 - .../y_string_u+2028_line_sep.json | 1 - .../test_parsing/y_string_u+2029_par_sep.json | 1 - .../test_parsing/y_string_uEscape.json | 1 - .../y_string_uescaped_newline.json | 1 - .../y_string_unescaped_char_delete.json | 1 - .../test_parsing/y_string_unicode.json | 1 - .../y_string_unicodeEscapedBackslash.json | 1 - .../test_parsing/y_string_unicode_2.json | 1 - .../y_string_unicode_U+10FFFE_nonchar.json | 1 - .../y_string_unicode_U+1FFFE_nonchar.json | 1 - ...tring_unicode_U+200B_ZERO_WIDTH_SPACE.json | 1 - ..._string_unicode_U+2064_invisible_plus.json | 1 - .../y_string_unicode_U+FDD0_nonchar.json | 1 - .../y_string_unicode_U+FFFE_nonchar.json | 1 - ...y_string_unicode_escaped_double_quote.json | 1 - .../test_parsing/y_string_utf8.json | 1 - .../y_string_with_del_character.json | 1 - .../y_structure_lonely_false.json | 1 - .../test_parsing/y_structure_lonely_int.json | 1 - .../y_structure_lonely_negative_real.json | 1 - .../test_parsing/y_structure_lonely_null.json | 1 - .../y_structure_lonely_string.json | 1 - .../test_parsing/y_structure_lonely_true.json | 1 - .../y_structure_string_empty.json | 1 - .../y_structure_trailing_newline.json | 1 - .../y_structure_true_in_array.json | 1 - .../y_structure_whitespace_array.json | 1 - test/c.test.ts | 86 +++ test/jsonc.test.ts | 265 -------- test/jsontestsuite.test.ts | 117 ---- 338 files changed, 1352 insertions(+), 2019 deletions(-) delete mode 100644 THIRD_PARTY_NOTICES.md delete mode 100644 embed-grammar.js delete mode 100644 go/go.mod delete mode 100644 go/go.sum delete mode 100644 go/jsonc.go delete mode 100644 go/jsonc_test.go delete mode 100644 jsonc-grammar.jsonic create mode 100644 src/c.ts delete mode 100644 src/jsonc.ts create mode 100644 src/matchers.ts create mode 100644 src/symbols.ts create mode 100644 src/tokens.ts delete mode 100644 test/JSONTestSuite/LICENSE delete mode 100644 test/JSONTestSuite/README.md delete mode 100644 test/JSONTestSuite/test_parsing/i_number_double_huge_neg_exp.json delete mode 100644 test/JSONTestSuite/test_parsing/i_number_huge_exp.json delete mode 100755 test/JSONTestSuite/test_parsing/i_number_neg_int_huge_exp.json delete mode 100755 test/JSONTestSuite/test_parsing/i_number_pos_double_huge_exp.json delete mode 100644 test/JSONTestSuite/test_parsing/i_number_real_neg_overflow.json delete mode 100644 test/JSONTestSuite/test_parsing/i_number_real_pos_overflow.json delete mode 100644 test/JSONTestSuite/test_parsing/i_number_real_underflow.json delete mode 100644 test/JSONTestSuite/test_parsing/i_number_too_big_neg_int.json delete mode 100644 test/JSONTestSuite/test_parsing/i_number_too_big_pos_int.json delete mode 100755 test/JSONTestSuite/test_parsing/i_number_very_big_negative_int.json delete mode 100644 test/JSONTestSuite/test_parsing/i_object_key_lone_2nd_surrogate.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_UTF-16LE_with_BOM.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_UTF-8_invalid_sequence.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_UTF8_surrogate_U+D800.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_and_escape_valid.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_pair.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_incomplete_surrogates_escape_valid.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_invalid_lonely_surrogate.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_invalid_surrogate.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_invalid_utf-8.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_inverted_surrogates_U+1D11E.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_iso_latin_1.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_lone_second_surrogate.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_lone_utf8_continuation_byte.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_not_in_unicode_range.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_overlong_sequence_2_bytes.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes.json delete mode 100755 test/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes_null.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_truncated-utf-8.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_utf16BE_no_BOM.json delete mode 100644 test/JSONTestSuite/test_parsing/i_string_utf16LE_no_BOM.json delete mode 100644 test/JSONTestSuite/test_parsing/i_structure_500_nested_arrays.json delete mode 100755 test/JSONTestSuite/test_parsing/i_structure_UTF-8_BOM_empty_object.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_1_true_without_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_a_invalid_utf8.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_colon_instead_of_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_comma_after_close.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_comma_and_number.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_double_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_double_extra_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_extra_close.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_extra_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_incomplete.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_incomplete_invalid_value.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_inner_array_no_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_invalid_utf8.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_items_separated_by_semicolon.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_just_comma.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_just_minus.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_missing_value.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_newlines_unclosed.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_number_and_comma.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_number_and_several_commas.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_spaces_vertical_tab_formfeed.json delete mode 100755 test/JSONTestSuite/test_parsing/n_array_star_inside.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_unclosed.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_unclosed_trailing_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_unclosed_with_new_lines.json delete mode 100644 test/JSONTestSuite/test_parsing/n_array_unclosed_with_object_inside.json delete mode 100644 test/JSONTestSuite/test_parsing/n_incomplete_false.json delete mode 100644 test/JSONTestSuite/test_parsing/n_incomplete_null.json delete mode 100644 test/JSONTestSuite/test_parsing/n_incomplete_true.json delete mode 100644 test/JSONTestSuite/test_parsing/n_multidigit_number_then_00.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_++.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_+1.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_+Inf.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_-01.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_-1.0..json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_-2..json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_-NaN.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_.-1.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_.2e-3.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_0.1.2.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_0.3e+.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_0.3e.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_0.e1.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_0_capital_E+.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_0_capital_E.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_0e+.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_0e.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_1.0e+.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_1.0e-.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_1.0e.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_1_000.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_1eE2.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_2.e+3.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_2.e-3.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_2.e3.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_9.e+.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_Inf.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_NaN.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_U+FF11_fullwidth_digit_one.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_expression.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_hex_1_digit.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_hex_2_digits.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_infinity.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_invalid+-.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_invalid-negative-real.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-bigger-int.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-exponent.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-int.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_minus_infinity.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_minus_sign_with_trailing_garbage.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_minus_space_1.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_neg_int_starting_with_zero.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_neg_real_without_int_part.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_neg_with_garbage_at_end.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_real_garbage_after_e.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_real_with_invalid_utf8_after_e.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_real_without_fractional_part.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_starting_with_dot.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_with_alpha.json delete mode 100644 test/JSONTestSuite/test_parsing/n_number_with_alpha_char.json delete mode 100755 test/JSONTestSuite/test_parsing/n_number_with_leading_zero.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_bad_value.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_bracket_key.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_comma_instead_of_colon.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_double_colon.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_emoji.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_garbage_at_end.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_key_with_single_quotes.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_missing_colon.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_missing_key.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_missing_semicolon.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_missing_value.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_no-colon.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_non_string_key.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_non_string_key_but_huge_number_instead.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_repeated_null_null.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_several_trailing_commas.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_single_quote.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_trailing_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_trailing_comment.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_trailing_comment_open.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.json delete mode 100755 test/JSONTestSuite/test_parsing/n_object_two_commas_in_a_row.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_unquoted_key.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_unterminated-value.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_with_single_string.json delete mode 100644 test/JSONTestSuite/test_parsing/n_object_with_trailing_garbage.json delete mode 100755 test/JSONTestSuite/test_parsing/n_single_space.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1x.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_accentuated_char_no_quotes.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_backslash_00.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_escape_x.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_escaped_backslash_bad.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_escaped_ctrl_char_tab.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_escaped_emoji.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_incomplete_escape.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_incomplete_escaped_character.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_incomplete_surrogate.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_incomplete_surrogate_escape_invalid.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_invalid-utf-8-in-escape.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_invalid_backslash_esc.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_invalid_unicode_escape.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_invalid_utf8_after_escape.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_leading_uescaped_thinspace.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_no_quotes_with_bad_escape.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_single_doublequote.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_single_quote.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_single_string_no_double_quotes.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_start_escape_unclosed.json delete mode 100755 test/JSONTestSuite/test_parsing/n_string_unescaped_ctrl_char.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_unescaped_newline.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_unescaped_tab.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_unicode_CapitalU.json delete mode 100644 test/JSONTestSuite/test_parsing/n_string_with_trailing_garbage.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_100000_opening_arrays.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_U+2060_word_joined.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_UTF8_BOM_no_data.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_angle_bracket_..json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_angle_bracket_null.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_array_trailing_garbage.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_array_with_extra_array_close.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_array_with_unclosed_string.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_ascii-unicode-identifier.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_capitalized_True.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_close_unopened_array.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_comma_instead_of_closing_brace.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_double_array.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_end_array.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_incomplete_UTF8_BOM.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_lone-invalid-utf-8.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_lone-open-bracket.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_no_data.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_null-byte-outside-string.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_number_with_trailing_garbage.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_object_followed_by_closing_object.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_object_unclosed_no_value.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_object_with_comment.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_object_with_trailing_garbage.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_array_apostrophe.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_array_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_array_object.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_array_open_object.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_array_open_string.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_array_string.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_object.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_open_object_close_array.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_object_comma.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_object_open_array.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_object_open_string.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_object_string_with_apostrophes.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_open_open.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_single_eacute.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_single_star.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_trailing_#.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_uescaped_LF_before_string.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_unclosed_array.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_unclosed_array_partial_null.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_false.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_true.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_unclosed_object.json delete mode 100644 test/JSONTestSuite/test_parsing/n_structure_unicode-identifier.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json delete mode 100755 test/JSONTestSuite/test_parsing/n_structure_whitespace_formfeed.json delete mode 100755 test/JSONTestSuite/test_parsing/y_array_arraysWithSpaces.json delete mode 100644 test/JSONTestSuite/test_parsing/y_array_empty-string.json delete mode 100755 test/JSONTestSuite/test_parsing/y_array_empty.json delete mode 100755 test/JSONTestSuite/test_parsing/y_array_ending_with_newline.json delete mode 100644 test/JSONTestSuite/test_parsing/y_array_false.json delete mode 100755 test/JSONTestSuite/test_parsing/y_array_heterogeneous.json delete mode 100644 test/JSONTestSuite/test_parsing/y_array_null.json delete mode 100644 test/JSONTestSuite/test_parsing/y_array_with_1_and_newline.json delete mode 100755 test/JSONTestSuite/test_parsing/y_array_with_leading_space.json delete mode 100755 test/JSONTestSuite/test_parsing/y_array_with_several_null.json delete mode 100755 test/JSONTestSuite/test_parsing/y_array_with_trailing_space.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number.json delete mode 100755 test/JSONTestSuite/test_parsing/y_number_0e+1.json delete mode 100755 test/JSONTestSuite/test_parsing/y_number_0e1.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_after_space.json delete mode 100755 test/JSONTestSuite/test_parsing/y_number_double_close_to_zero.json delete mode 100755 test/JSONTestSuite/test_parsing/y_number_int_with_exp.json delete mode 100755 test/JSONTestSuite/test_parsing/y_number_minus_zero.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_negative_int.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_negative_one.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_negative_zero.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_real_capital_e.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_real_capital_e_neg_exp.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_real_capital_e_pos_exp.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_real_exponent.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_real_fraction_exponent.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_real_neg_exp.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_real_pos_exponent.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_simple_int.json delete mode 100644 test/JSONTestSuite/test_parsing/y_number_simple_real.json delete mode 100755 test/JSONTestSuite/test_parsing/y_object.json delete mode 100755 test/JSONTestSuite/test_parsing/y_object_basic.json delete mode 100755 test/JSONTestSuite/test_parsing/y_object_duplicated_key.json delete mode 100755 test/JSONTestSuite/test_parsing/y_object_duplicated_key_and_value.json delete mode 100644 test/JSONTestSuite/test_parsing/y_object_empty.json delete mode 100755 test/JSONTestSuite/test_parsing/y_object_empty_key.json delete mode 100644 test/JSONTestSuite/test_parsing/y_object_escaped_null_in_key.json delete mode 100644 test/JSONTestSuite/test_parsing/y_object_extreme_numbers.json delete mode 100644 test/JSONTestSuite/test_parsing/y_object_long_strings.json delete mode 100644 test/JSONTestSuite/test_parsing/y_object_simple.json delete mode 100644 test/JSONTestSuite/test_parsing/y_object_string_unicode.json delete mode 100644 test/JSONTestSuite/test_parsing/y_object_with_newlines.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pair.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pairs.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_allowed_escapes.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_backslash_and_u_escaped_zero.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_backslash_doublequotes.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_comments.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_double_escape_a.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_double_escape_n.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_escaped_control_character.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_escaped_noncharacter.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_in_array.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_in_array_with_leading_space.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_last_surrogates_1_and_2.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_nbsp_uescaped.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_null_escape.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_one-byte-utf-8.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_pi.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_simple_ascii.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_space.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_three-byte-utf-8.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_two-byte-utf-8.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_u+2028_line_sep.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_u+2029_par_sep.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_uEscape.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_uescaped_newline.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_unescaped_char_delete.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_unicode.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_unicodeEscapedBackslash.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_unicode_2.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_unicode_U+10FFFE_nonchar.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_unicode_U+1FFFE_nonchar.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_unicode_U+FDD0_nonchar.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_unicode_U+FFFE_nonchar.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_unicode_escaped_double_quote.json delete mode 100644 test/JSONTestSuite/test_parsing/y_string_utf8.json delete mode 100755 test/JSONTestSuite/test_parsing/y_string_with_del_character.json delete mode 100644 test/JSONTestSuite/test_parsing/y_structure_lonely_false.json delete mode 100755 test/JSONTestSuite/test_parsing/y_structure_lonely_int.json delete mode 100755 test/JSONTestSuite/test_parsing/y_structure_lonely_negative_real.json delete mode 100644 test/JSONTestSuite/test_parsing/y_structure_lonely_null.json delete mode 100755 test/JSONTestSuite/test_parsing/y_structure_lonely_string.json delete mode 100755 test/JSONTestSuite/test_parsing/y_structure_lonely_true.json delete mode 100644 test/JSONTestSuite/test_parsing/y_structure_string_empty.json delete mode 100644 test/JSONTestSuite/test_parsing/y_structure_trailing_newline.json delete mode 100644 test/JSONTestSuite/test_parsing/y_structure_true_in_array.json delete mode 100644 test/JSONTestSuite/test_parsing/y_structure_whitespace_array.json create mode 100644 test/c.test.ts delete mode 100644 test/jsonc.test.ts delete mode 100644 test/jsontestsuite.test.ts diff --git a/Makefile b/Makefile index 3558e3d..137b5db 100644 --- a/Makefile +++ b/Makefile @@ -1,55 +1,15 @@ -.PHONY: all build test clean embed build-ts build-go test-ts test-go clean-ts clean-go publish-go tags-go tidy-go reset +.PHONY: all build test clean reset all: build test -build: build-ts build-go - -test: test-ts test-go - -clean: clean-ts clean-go - -# Embed jsonc-grammar.jsonic into src/jsonc.ts and go/jsonc.go. -embed: - node embed-grammar.js - -# TypeScript -build-ts: +build: npm run build -test-ts: +test: npm test -clean-ts: +clean: rm -rf dist dist-test -# Go -build-go: embed - cd go && go build ./... - -test-go: - cd go && go test ./... - -clean-go: - cd go && go clean -cache - -# Publish Go module: make publish-go V=0.1.1 -publish-go: test-go - @test -n "$(V)" || (echo "Usage: make publish-go V=x.y.z" && exit 1) - sed -i '' 's/^const Version = ".*"/const Version = "$(V)"/' go/jsonc.go - git add go/jsonc.go - git commit -m "go: v$(V)" - git tag go/v$(V) - git push origin main go/v$(V) - if command -v gh >/dev/null 2>&1; then gh release create go/v$(V) --title "go/v$(V)" --notes "Go module release v$(V)"; fi - -tidy-go: - cd go && go mod tidy - -tags-go: - git tag -l 'go/v*' --sort=-version:refname - reset: npm run reset - cd go && go clean -cache - cd go && go build ./... - cd go && go test -v ./... diff --git a/README.md b/README.md index c722c0e..221d559 100644 --- a/README.md +++ b/README.md @@ -1,243 +1,74 @@ -# @jsonic/jsonc - -This plugin allows the [Jsonic](https://jsonic.senecajs.org) JSON parser -to parse [JSONC](https://github.com/microsoft/node-jsonc-parser) format -files (JSON with Comments). - -JSONC is a strict superset of JSON that adds single-line (`//`) and -block (`/* */`) comments. Trailing commas in objects and arrays can be -optionally enabled. - -[![npm version](https://img.shields.io/npm/v/@jsonic/jsonc.svg)](https://npmjs.com/package/@jsonic/jsonc) -[![build](https://github.com/jsonicjs/jsonc/actions/workflows/build.yml/badge.svg)](https://github.com/jsonicjs/jsonc/actions/workflows/build.yml) -[![Coverage Status](https://coveralls.io/repos/github/jsonicjs/jsonc/badge.svg?branch=main)](https://coveralls.io/github/jsonicjs/jsonc?branch=main) -[![Known Vulnerabilities](https://snyk.io/test/github/jsonicjs/jsonc/badge.svg)](https://snyk.io/test/github/jsonicjs/jsonc) - - -| ![Voxgig](https://www.voxgig.com/res/img/vgt01r.png) | This open source module is sponsored and supported by [Voxgig](https://www.voxgig.com). | -| ---------------------------------------------------- | --------------------------------------------------------------------------------------- | - - -The documentation below is organized along the -[Diátaxis](https://diataxis.fr) quadrants: - -- [Quick start](#quick-start) — tutorial -- [How-to guides](#how-to-guides) — task recipes -- [Reference](#reference) — API surface -- [JSONC format](#jsonc-format) — explanation - +# @jsonic/c + +A [Jsonic](https://jsonic.senecajs.org) plugin that parses **C source code** +into a **concrete syntax tree** — preserving every token, comment, macro +definition, macro use, and compiler extension as-is. + +> Status: **early.** The architecture (lex matchers + symbol/macro tables +> on `Context.meta` + grammar rules) is in place and validated by smoke +> tests for tokenization and typedef-name disambiguation. The grammar +> itself is intentionally coarse-grained for now (each external +> declaration is captured as a token sequence) and is being filled in +> stage by stage. + +## Goals + +- Concrete syntax tree, not a semantic AST. Every source token survives. +- Macros preserved. `#define` definitions become directive nodes; macro + invocations stay as identifier expressions tagged `isMacro: true` when + the name was previously seen in a `#define`. +- Compiler extensions (GCC, Clang, MSVC) recognized as keywords: + `__attribute__`, `__declspec`, `__asm__`, `__typeof__`, `_Generic`, + `_Static_assert`, `__int64`, etc. +- C23 standard target (`constexpr`, `nullptr`, `typeof`, `_BitInt`, …). +- Best-effort handling of `#if/#ifdef` conditional groups with opaque + fallback per branch when a branch can't be parsed cleanly. +- Full nested scoping for typedef-name disambiguation + (file → function → block → struct/union → enum → for-init). + +## Architecture + +- **Focused lex matchers** (`src/matchers.ts`): one matcher per concept — + whitespace, line continuation, line/block comments, preprocessor + directive opener, directive newline, header name, identifier (with + keyword/typedef-name/macro-name reclassification), integer, float, + char, string, punctuator dispatch. + +- **Symbol & macro tables** (`src/symbols.ts`): scope stack and macro + lookup live on `ctx.meta.cmeta` so both lex matchers and rule actions + share state. Lex matchers consult the symbol table when classifying + identifiers; rule actions register names when they finalize a + `typedef`/`#define`. Pre-lexed lookahead tokens are reclassified in + place when a typedef is registered, so the next match sees the + updated classification immediately. + +- **Token catalog** (`src/tokens.ts`): every C23 keyword, every + compiler-extension keyword, and every punctuator gets its own named + token. Grammar rules reference these names directly. + +- **Plugin entry** (`src/c.ts`): wires matchers and the symbol/macro + tables, then defines grammar rules via `jsonic.rule(...)`. Uses + `Rule.k` (propagated across `r:` recursion) for state that must + survive the iteration of token-level rules. ## Quick start -### TypeScript - -Install: - -```bash -npm install @jsonic/jsonc @jsonic/jsonic-next -``` - -Parse: - -```typescript -import { Jsonic } from '@jsonic/jsonic-next' -import { Jsonc } from '@jsonic/jsonc' - -const j = Jsonic.make().use(Jsonc) - -const result = j('{ "name": "app", /* version */ "version": "1.0" }') -// => { name: 'app', version: '1.0' } -``` - -### Go - -Install: - -```bash -go get github.com/jsonicjs/jsonc/go -``` - -Parse: - -```go -package main - -import ( - "fmt" - jsonic "github.com/jsonicjs/jsonic/go" - jsonc "github.com/jsonicjs/jsonc/go" -) - -func main() { - j := jsonic.Make() - j.Use(jsonc.Jsonc) - - result, err := j.Parse(`{ "name": "app", /* version */ "version": "1.0" }`) - if err != nil { - panic(err) - } - fmt.Println(result) - // => map[name:app version:1.0] -} -``` - - -## How-to guides - -### Allow trailing commas - -TypeScript: - -```typescript -const j = Jsonic.make().use(Jsonc, { allowTrailingComma: true }) -j('{ "debug": true, "verbose": false, }') -// => { debug: true, verbose: false } -``` - -Go: - -```go -j := jsonic.Make() -j.Use(jsonc.Jsonc, map[string]any{"allowTrailingComma": true}) -result, _ := j.Parse(`{ "debug": true, "verbose": false, }`) -``` - -### Parse strict JSON (disable comments) - -TypeScript: - -```typescript -const j = Jsonic.make().use(Jsonc, { disallowComments: true }) -j('{ "foo": /* not allowed */ true }') // throws -``` - -Go: - -```go -j := jsonic.Make() -j.Use(jsonc.Jsonc, map[string]any{"disallowComments": true}) -``` - -### Handle parse errors - -TypeScript — parse errors throw: - -```typescript -try { - j('{ "bad": }') -} catch (err) { - console.error(err.message) -} -``` - -Go — errors are returned: - -```go -if _, err := j.Parse(`{ "bad": }`); err != nil { - fmt.Println(err) -} -``` - -### Parse a file - -TypeScript: - -```typescript -import { readFileSync } from 'node:fs' -const j = Jsonic.make().use(Jsonc, { allowTrailingComma: true }) -const config = j(readFileSync('tsconfig.json', 'utf8')) -``` - -Go: - -```go -src, _ := os.ReadFile("tsconfig.json") -j := jsonic.Make() -j.Use(jsonc.Jsonc, map[string]any{"allowTrailingComma": true}) -config, _ := j.Parse(string(src)) -``` - - -## Reference - -### TypeScript +```ts +import { Jsonic } from 'jsonic' +import { C } from '@jsonic/c' -```typescript -function Jsonc(jsonic: Jsonic, options?: JsoncOptions): void +const j = Jsonic.make().use(C) -type JsoncOptions = { - allowTrailingComma?: boolean // default: false - disallowComments?: boolean // default: false -} -``` - -Register with `jsonic.use(Jsonc, options?)`. After registration, invoke -the jsonic instance as a function on a source string; it returns the -parsed value or throws on syntax errors. - -| Option | Type | Default | Effect | -|--------|------|---------|--------| -| `allowTrailingComma` | `boolean` | `false` | Permit a trailing comma before `}` and `]` | -| `disallowComments` | `boolean` | `false` | Reject `//` and `/* */` comments (strict JSON) | +const cst = j(` + typedef int T; + T x; +`) -### Go - -```go -func Jsonc(j *jsonic.Jsonic, pluginOpts map[string]any) error +// cst.kind === 'translation_unit' +// cst.children is an ordered list of external_declaration nodes, +// each carrying their tokens as token-refs preserving source spans. ``` -Register with `j.Use(jsonc.Jsonc)` or `j.Use(jsonc.Jsonc, opts)` where -`opts` is a `map[string]any`. `Parse` then returns `(any, error)` — -`map[string]any` for objects, `[]any` for arrays, `float64` for numbers, -`string`, `bool`, or `nil`. - -| Key | Type | Default | Effect | -|-----|------|---------|--------| -| `allowTrailingComma` | `bool` | `false` | Permit a trailing comma before `}` and `]` | -| `disallowComments` | `bool` | `false` | Reject `//` and `/* */` comments (strict JSON) | - - -## JSONC format - -JSONC follows [RFC 8259](https://tools.ietf.org/html/rfc8259) (JSON) -with these extensions: - -- **Line comments**: `//` to end of line -- **Block comments**: `/* */` (non-nesting) -- **Trailing commas**: optional, in objects and arrays - -All other JSON rules apply: - -- Strings must be double-quoted -- Standard escapes only: `\"` `\\` `\/` `\b` `\f` `\n` `\r` `\t` `\uXXXX` -- Numbers: integer, decimal, scientific notation (no hex, octal, binary) -- Keywords: `true`, `false`, `null` (case-sensitive) -- Property names must be double-quoted strings - -### Conformance notes - -The plugin layers JSONC rules on top of jsonic, which is intentionally -lenient in some places vs. strict RFC 8259. The test suite runs the -[nst/JSONTestSuite](https://github.com/nst/JSONTestSuite) corpus in -strict mode (`disallowComments: true`) and pins the known-lenient -cases in `test/jsontestsuite.test.ts` (see `N_KNOWN_LENIENT`). Examples -of accepted-but-non-RFC input include numbers with leading zeros and -unquoted object keys. Use an RFC-strict parser if byte-perfect RFC 8259 -rejection is required. - - -## Acknowledgments - -Conformance testing uses third-party corpora under MIT License: - -- [nst/JSONTestSuite](https://github.com/nst/JSONTestSuite) by Nicolas - Seriot — vendored at `test/JSONTestSuite/` (the `test_parsing/` corpus). -- [microsoft/node-jsonc-parser](https://github.com/microsoft/node-jsonc-parser) — - parse-level test cases ported into `test/jsonc.test.ts`. - -See [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md) for details. - - ## License -MIT. Copyright (c) 2021-2025 Richard Rodger and contributors. +MIT. Copyright (c) 2026 Richard Rodger and contributors. diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md deleted file mode 100644 index 3362e95..0000000 --- a/THIRD_PARTY_NOTICES.md +++ /dev/null @@ -1,50 +0,0 @@ -# Third-Party Notices - -This project incorporates material from the projects listed below. The -original copyright notices and license texts are preserved as required. - -## nst/JSONTestSuite - -Vendored at `test/JSONTestSuite/` for RFC 8259 conformance testing via -`test/jsontestsuite.test.ts`. Only the `test_parsing/` corpus, `LICENSE`, -and `README.md` from the upstream project are included; the upstream -`LICENSE` is preserved in place. - -- Project: https://github.com/nst/JSONTestSuite -- License: MIT -- Copyright (c) 2016 Nicolas Seriot - -## microsoft/node-jsonc-parser - -Parse-level test cases in `test/jsonc.test.ts` were ported from -`src/test/json.test.ts` of `microsoft/node-jsonc-parser`. - -- Project: https://github.com/microsoft/node-jsonc-parser -- License: MIT -- Copyright (c) Microsoft Corporation - ---- - -Both projects are distributed under the MIT License. Full license text: - -``` -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -``` diff --git a/embed-grammar.js b/embed-grammar.js deleted file mode 100644 index 1188a35..0000000 --- a/embed-grammar.js +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env node - -// Embed jsonc-grammar.jsonic into TypeScript and Go source files. -// Run via: npm run embed (or: node embed-grammar.js) - -const fs = require('fs') -const path = require('path') - -const GRAMMAR_FILE = path.join(__dirname, 'jsonc-grammar.jsonic') -const TS_FILE = path.join(__dirname, 'src', 'jsonc.ts') -const GO_FILE = path.join(__dirname, 'go', 'jsonc.go') - -const BEGIN = '// --- BEGIN EMBEDDED jsonc-grammar.jsonic ---' -const END = '// --- END EMBEDDED jsonc-grammar.jsonic ---' - -const grammar = fs.readFileSync(GRAMMAR_FILE, 'utf8') - -// --- TypeScript embedding --- -function embedTS() { - let src = fs.readFileSync(TS_FILE, 'utf8') - const startIdx = src.indexOf(BEGIN) - const endIdx = src.indexOf(END) - if (startIdx === -1 || endIdx === -1) { - console.error('TS markers not found in', TS_FILE) - process.exit(1) - } - - // Escape backticks and template expressions for a JS template literal. - const escaped = grammar - .replace(/\\/g, '\\\\') - .replace(/`/g, '\\`') - .replace(/\$\{/g, '\\${') - - const replacement = - BEGIN + - '\nconst grammarText = `\n' + - escaped + - '`\n' + - END - - src = src.substring(0, startIdx) + replacement + src.substring(endIdx + END.length) - fs.writeFileSync(TS_FILE, src) - console.log('Embedded grammar into', TS_FILE) -} - -// --- Go embedding --- -function embedGo() { - let src = fs.readFileSync(GO_FILE, 'utf8') - const startIdx = src.indexOf(BEGIN) - const endIdx = src.indexOf(END) - if (startIdx === -1 || endIdx === -1) { - console.error('Go markers not found in', GO_FILE) - process.exit(1) - } - - if (grammar.includes('`')) { - console.error('Grammar contains backticks, incompatible with Go raw strings') - process.exit(1) - } - - const replacement = - BEGIN + - '\nconst grammarText = `\n' + - grammar + - '`\n' + - END - - src = src.substring(0, startIdx) + replacement + src.substring(endIdx + END.length) - fs.writeFileSync(GO_FILE, src) - console.log('Embedded grammar into', GO_FILE) -} - -embedTS() -embedGo() diff --git a/go/go.mod b/go/go.mod deleted file mode 100644 index f58d839..0000000 --- a/go/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/jsonicjs/jsonc/go - -go 1.24.7 - -require github.com/jsonicjs/jsonic/go v0.1.22 diff --git a/go/go.sum b/go/go.sum deleted file mode 100644 index 5c34bfc..0000000 --- a/go/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/jsonicjs/jsonic/go v0.1.22 h1:sam238fTyjDq0nby9TYS+aCCHprLl91ArQPWLCg2O0Y= -github.com/jsonicjs/jsonic/go v0.1.22/go.mod h1:ObNKlCG7esWoi4AHCpdgkILvPINV8bpvkbCd4llGGUg= diff --git a/go/jsonc.go b/go/jsonc.go deleted file mode 100644 index 3bc74e5..0000000 --- a/go/jsonc.go +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (c) 2021-2025 Richard Rodger, MIT License */ - -package jsonc - -import ( - jsonic "github.com/jsonicjs/jsonic/go" -) - -const Version = "0.1.2" - -// --- BEGIN EMBEDDED jsonc-grammar.jsonic --- -const grammarText = ` -# JSONC Grammar Definition -# Parsed by a standard Jsonic instance and passed to jsonic.grammar() -# Extends standard JSON grammar with end-of-input value handling. - -{ - options: text: { lex: false } - options: number: { hex: false oct: false bin: false sep: null exclude: "@/^\\./" } - options: string: { chars: '"' multiChars: '' allowUnknown: false } - options: string: escape: { v: null } - options: map: { extend: false } - options: lex: { empty: false } - options: rule: { finish: false } - - rule: val: open: { - alts: [ - { s: '#ZZ' g: jsonc } - ] - inject: { append: true } - } - - rule: pair: close: { - alts: [ - { s: '#CA #CB' b: 1 g: comma } - ] - inject: {} - } - - rule: elem: close: { - alts: [ - { s: '#CA #CS' b: 1 g: comma } - ] - inject: {} - } -} -` -// --- END EMBEDDED jsonc-grammar.jsonic --- - -// Jsonc configures a jsonic instance for JSONC parsing. -func Jsonc(j *jsonic.Jsonic, pluginOpts map[string]any) error { - commentLex := true != toBool(pluginOpts["disallowComments"]) - ruleExclude := "comma" - if toBool(pluginOpts["allowTrailingComma"]) { - ruleExclude = "" - } - - // Apply grammar: static options, rules, and trailing comma alts. - if err := j.GrammarText(grammarText, &jsonic.GrammarSetting{ - Rule: &jsonic.GrammarSettingRule{ - Alt: &jsonic.GrammarSettingAlt{G: "jsonc"}, - }, - }); err != nil { - return err - } - - // Runtime options that depend on plugin arguments. - j.SetOptions(jsonic.Options{ - Comment: &jsonic.CommentOptions{Lex: &commentLex}, - Rule: &jsonic.RuleOptions{ - Include: "jsonc,json", - Exclude: ruleExclude, - }, - }) - - return nil -} - -func toBool(v any) bool { - b, _ := v.(bool) - return b -} diff --git a/go/jsonc_test.go b/go/jsonc_test.go deleted file mode 100644 index fd93e3f..0000000 --- a/go/jsonc_test.go +++ /dev/null @@ -1,634 +0,0 @@ -/* Copyright (c) 2021-2025 Richard Rodger, MIT License */ - -package jsonc - -import ( - "reflect" - "strings" - "testing" - - jsonic "github.com/jsonicjs/jsonic/go" -) - -func makeJsonc(opts ...map[string]any) *jsonic.Jsonic { - j := jsonic.Make() - if len(opts) > 0 { - j.Use(Jsonc, opts[0]) - } else { - j.Use(Jsonc) - } - return j -} - -func assert(t *testing.T, name string, got, want any) { - t.Helper() - if !reflect.DeepEqual(got, want) { - t.Errorf("%s:\n got: %#v\n want: %#v", name, got, want) - } -} - -func assertError(t *testing.T, name string, err error, contains string) { - t.Helper() - if err == nil { - t.Errorf("%s: expected error containing %q, got nil", name, contains) - return - } - if !strings.Contains(err.Error(), contains) { - t.Errorf("%s: expected error containing %q, got: %v", name, contains, err) - } -} - -var j = makeJsonc() - -func parse(src string) (any, error) { return j.Parse(src) } - -func TestHappy(t *testing.T) { - r, err := parse(`{"a":1}`) - if err != nil { - t.Fatal(err) - } - assert(t, "basic", r, map[string]any{"a": float64(1)}) -} - -func TestComments(t *testing.T) { - r, err := parse("// this is a comment") - if err != nil { - t.Fatal(err) - } - assert(t, "single-line", r, nil) - - r, err = parse("// this is a comment\n") - if err != nil { - t.Fatal(err) - } - assert(t, "single-line-newline", r, nil) - - r, err = parse("/* this is a comment*/") - if err != nil { - t.Fatal(err) - } - assert(t, "block", r, nil) - - r, err = parse("/* this is a \r\ncomment*/") - if err != nil { - t.Fatal(err) - } - assert(t, "block-crlf", r, nil) - - r, err = parse("/* this is a \ncomment*/") - if err != nil { - t.Fatal(err) - } - assert(t, "block-lf", r, nil) - - _, err = parse("/* this is a") - assertError(t, "unterminated-block", err, "unterminated_comment") - - _, err = parse("/* this is a \ncomment") - assertError(t, "unterminated-block-multiline", err, "unterminated_comment") - - _, err = parse("/ ttt") - assertError(t, "invalid-comment", err, "unexpected") -} - -func TestStrings(t *testing.T) { - r, err := parse(`"test"`) - if err != nil { - t.Fatal(err) - } - assert(t, "simple", r, "test") - - r, _ = parse(`"\""`) - assert(t, "escape-quote", r, `"`) - - r, _ = parse(`"\/"`) - assert(t, "escape-slash", r, "/") - - r, _ = parse(`"\b"`) - assert(t, "escape-backspace", r, "\b") - - r, _ = parse(`"\f"`) - assert(t, "escape-formfeed", r, "\f") - - r, _ = parse(`"\n"`) - assert(t, "escape-newline", r, "\n") - - r, _ = parse(`"\r"`) - assert(t, "escape-return", r, "\r") - - r, _ = parse(`"\t"`) - assert(t, "escape-tab", r, "\t") - - r, _ = parse(`"\u00DC"`) - assert(t, "unicode", r, "\u00DC") - - // Note: \v is accepted by the jsonic Go string matcher as a built-in escape. - // This is a minor deviation from strict JSONC spec which only allows - // \", \\, \/, \b, \f, \n, \r, \t, and \uXXXX. - - _, err = parse(`"test`) - assertError(t, "unterminated", err, "unterminated_string") -} - -func TestNumbers(t *testing.T) { - r, _ := parse("0") - assert(t, "zero", r, float64(0)) - - r, _ = parse("0.1") - assert(t, "decimal", r, 0.1) - - r, _ = parse("-0.1") - assert(t, "neg-decimal", r, -0.1) - - r, _ = parse("-1") - assert(t, "neg", r, float64(-1)) - - r, _ = parse("1") - assert(t, "one", r, float64(1)) - - r, _ = parse("123456789") - assert(t, "large", r, float64(123456789)) - - r, _ = parse("10") - assert(t, "ten", r, float64(10)) - - r, _ = parse("90") - assert(t, "ninety", r, float64(90)) - - r, _ = parse("90E+123") - assert(t, "sci-upper-plus", r, 90E+123) - - r, _ = parse("90e+123") - assert(t, "sci-lower-plus", r, 90e+123) - - r, _ = parse("90e-123") - assert(t, "sci-lower-minus", r, 90e-123) - - r, _ = parse("90E-123") - assert(t, "sci-upper-minus", r, 90E-123) - - r, _ = parse("90E123") - assert(t, "sci-upper", r, 90E123) - - r, _ = parse("90e123") - assert(t, "sci-lower", r, 90e123) - - _, err := parse("-") - if err == nil { - t.Error("expected error for bare minus") - } - - _, err = parse(".0") - if err == nil { - t.Error("expected error for leading dot number") - } -} - -func TestKeywords(t *testing.T) { - r, _ := parse("true") - assert(t, "true", r, true) - - r, _ = parse("false") - assert(t, "false", r, false) - - r, _ = parse("null") - assert(t, "null", r, nil) - - _, err := parse("True") - if err == nil { - t.Error("expected error for capitalized True") - } - - r, _ = parse("false//hello") - assert(t, "value-with-comment", r, false) -} - -func TestTrivia(t *testing.T) { - r, _ := parse(" ") - assert(t, "space", r, nil) - - r, _ = parse(" \t ") - assert(t, "tabs", r, nil) - - r, _ = parse(" \t \n \t ") - assert(t, "tabs-newlines", r, nil) - - r, _ = parse("\r\n") - assert(t, "crlf", r, nil) - - r, _ = parse("\r") - assert(t, "cr", r, nil) - - r, _ = parse("\n") - assert(t, "lf", r, nil) - - r, _ = parse("\n\r") - assert(t, "lfcr", r, nil) - - r, _ = parse("\n \n") - assert(t, "newlines-spaces", r, nil) -} - -func TestLiterals(t *testing.T) { - r, _ := parse("true") - assert(t, "true", r, true) - - r, _ = parse("false") - assert(t, "false", r, false) - - r, _ = parse("null") - assert(t, "null", r, nil) - - r, _ = parse(`"foo"`) - assert(t, "string", r, "foo") - - r, _ = parse(`"\"-\\-\/-\b-\f-\n-\r-\t"`) - assert(t, "escapes", r, "\"-\\-/-\b-\f-\n-\r-\t") - - r, _ = parse(`"\u00DC"`) - assert(t, "unicode", r, "\u00DC") - - r, _ = parse("9") - assert(t, "nine", r, float64(9)) - - r, _ = parse("-9") - assert(t, "neg-nine", r, float64(-9)) - - r, _ = parse("0.129") - assert(t, "decimal", r, 0.129) - - r, _ = parse("23e3") - assert(t, "sci", r, 23e3) - - r, _ = parse("1.2E+3") - assert(t, "sci-plus", r, 1.2E+3) - - r, _ = parse("1.2E-3") - assert(t, "sci-minus", r, 1.2E-3) - - r, _ = parse("1.2E-3 // comment") - assert(t, "num-comment", r, 1.2E-3) -} - -func TestObjects(t *testing.T) { - r, _ := parse("{}") - assert(t, "empty", r, map[string]any{}) - - r, _ = parse(`{ "foo": true }`) - assert(t, "one-field", r, map[string]any{"foo": true}) - - r, _ = parse(`{ "bar": 8, "xoo": "foo" }`) - assert(t, "two-fields", r, map[string]any{"bar": float64(8), "xoo": "foo"}) - - r, _ = parse(`{ "hello": [], "world": {} }`) - assert(t, "empty-nested", r, map[string]any{"hello": []any{}, "world": map[string]any{}}) - - r, _ = parse(`{ "a": false, "b": true, "c": [ 7.4 ] }`) - assert(t, "mixed", r, map[string]any{"a": false, "b": true, "c": []any{7.4}}) - - r, _ = parse(`{ "hello": { "again": { "inside": 5 }, "world": 1 }}`) - assert(t, "deep-nested", r, map[string]any{ - "hello": map[string]any{ - "again": map[string]any{"inside": float64(5)}, - "world": float64(1), - }, - }) - - r, _ = parse(`{ "foo": /*hello*/true }`) - assert(t, "comment-in-obj", r, map[string]any{"foo": true}) - - r, _ = parse(`{ "": true }`) - assert(t, "empty-key", r, map[string]any{"": true}) -} - -func TestArrays(t *testing.T) { - r, _ := parse("[]") - assert(t, "empty", r, []any{}) - - r, _ = parse("[ [], [ [] ]]") - assert(t, "nested-empty", r, []any{[]any{}, []any{[]any{}}}) - - r, _ = parse("[ 1, 2, 3 ]") - assert(t, "numbers", r, []any{float64(1), float64(2), float64(3)}) - - r, _ = parse(`[ { "a": null } ]`) - assert(t, "obj-in-array", r, []any{map[string]any{"a": nil}}) -} - -func TestObjectErrors(t *testing.T) { - _, err := parse("{,}") - if err == nil { - t.Error("expected error for leading comma in object") - } - - _, err = parse(`{ "foo": true, }`) - if err == nil { - t.Error("expected error for trailing comma in object (default)") - } - - _, err = parse(`{ "bar": 8 "xoo": "foo" }`) - if err == nil { - t.Error("expected error for missing comma in object") - } - - _, err = parse(`{ ,"bar": 8 }`) - if err == nil { - t.Error("expected error for leading comma") - } - - _, err = parse(`{ "bar": 8, "foo": }`) - if err == nil { - t.Error("expected error for missing value") - } - - _, err = parse(`{ 8, "foo": 9 }`) - if err == nil { - t.Error("expected error for number as key") - } -} - -func TestArrayErrors(t *testing.T) { - _, err := parse("[,]") - if err == nil { - t.Error("expected error for leading comma in array") - } - - _, err = parse("[ 1 2, 3 ]") - if err == nil { - t.Error("expected error for missing comma in array") - } - - _, err = parse("[ ,1, 2, 3 ]") - if err == nil { - t.Error("expected error for leading comma in array") - } - - _, err = parse("[ ,1, 2, 3, ]") - if err == nil { - t.Error("expected error for commas in array") - } -} - -func TestErrors(t *testing.T) { - _, err := parse("1,1") - if err == nil { - t.Error("expected error for extra content after value") - } - - _, err = parse("") - if err == nil { - t.Error("expected error for empty input") - } -} - -func TestDisallowComments(t *testing.T) { - nc := makeJsonc(map[string]any{"disallowComments": true}) - - r, err := nc.Parse(`[ 1, 2, null, "foo" ]`) - if err != nil { - t.Fatal(err) - } - assert(t, "array", r, []any{float64(1), float64(2), nil, "foo"}) - - r, err = nc.Parse(`{ "hello": [], "world": {} }`) - if err != nil { - t.Fatal(err) - } - assert(t, "object", r, map[string]any{"hello": []any{}, "world": map[string]any{}}) - - _, err = nc.Parse(`{ "foo": /*comment*/ true }`) - if err == nil { - t.Error("expected error for comment when comments are disallowed") - } -} - -func TestTrailingComma(t *testing.T) { - jc := makeJsonc(map[string]any{"allowTrailingComma": true}) - - r, err := jc.Parse(`{ "hello": [], }`) - if err != nil { - t.Fatal(err) - } - assert(t, "obj-trailing", r, map[string]any{"hello": []any{}}) - - r, err = jc.Parse(`{ "hello": [] }`) - if err != nil { - t.Fatal(err) - } - assert(t, "obj-no-trailing", r, map[string]any{"hello": []any{}}) - - r, err = jc.Parse(`{ "hello": [], "world": {}, }`) - if err != nil { - t.Fatal(err) - } - assert(t, "obj-multi-trailing", r, map[string]any{"hello": []any{}, "world": map[string]any{}}) - - r, err = jc.Parse(`[ 1, 2, ]`) - if err != nil { - t.Fatal(err) - } - assert(t, "arr-trailing", r, []any{float64(1), float64(2)}) - - r, err = jc.Parse(`[ 1, 2 ]`) - if err != nil { - t.Fatal(err) - } - assert(t, "arr-no-trailing", r, []any{float64(1), float64(2)}) - - // Default parser should reject trailing commas. - _, err = j.Parse(`{ "hello": [], }`) - if err == nil { - t.Error("expected error for trailing comma with default options") - } - - _, err = j.Parse(`[ 1, 2, ]`) - if err == nil { - t.Error("expected error for trailing comma in array with default options") - } -} - -func TestMisc(t *testing.T) { - r, _ := j.Parse(`{ "foo": "bar" }`) - assert(t, "simple-obj", r, map[string]any{"foo": "bar"}) - - r, _ = j.Parse(`{ "foo": {"bar": 1, "car": 2 } }`) - assert(t, "nested-obj", r, map[string]any{ - "foo": map[string]any{"bar": float64(1), "car": float64(2)}, - }) - - r, _ = j.Parse(`{ "foo": {"bar": 1, "car": 8 }, "goo": {} }`) - assert(t, "multi-nested", r, map[string]any{ - "foo": map[string]any{"bar": float64(1), "car": float64(8)}, - "goo": map[string]any{}, - }) - - _, err := j.Parse(`{ "dep": {"bar": 1, "car": `) - if err == nil { - t.Error("expected error for unterminated object") - } - - _, err = j.Parse(`{ "dep": {"bar": 1,, "car": `) - if err == nil { - t.Error("expected error for double comma") - } - - _, err = j.Parse(`{ "dep": {"bar": "na", "dar": "ma", "car": } }`) - if err == nil { - t.Error("expected error for missing value") - } - - r, _ = j.Parse(`["foo", null ]`) - assert(t, "arr-mixed", r, []any{"foo", nil}) - - _, err = j.Parse(`["foo", null, ]`) - if err == nil { - t.Error("expected error for trailing comma in array") - } - - _, err = j.Parse(`["foo", null,, ]`) - if err == nil { - t.Error("expected error for double comma in array") - } - - r, _ = j.Parse("true") - assert(t, "bare-true", r, true) - - r, _ = j.Parse("false") - assert(t, "bare-false", r, false) - - r, _ = j.Parse("null") - assert(t, "bare-null", r, nil) - - r, _ = j.Parse("23") - assert(t, "bare-num", r, float64(23)) - - r, _ = j.Parse("-1.93e-19") - assert(t, "sci-notation", r, -1.93e-19) - - r, _ = j.Parse(`"hello"`) - assert(t, "bare-string", r, "hello") - - r, _ = j.Parse("[]") - assert(t, "empty-arr", r, []any{}) - - r, _ = j.Parse("[ 1 ]") - assert(t, "single-arr", r, []any{float64(1)}) - - r, _ = j.Parse(`[ 1, "x"]`) - assert(t, "mixed-arr", r, []any{float64(1), "x"}) - - r, _ = j.Parse("[[]]") - assert(t, "nested-arr", r, []any{[]any{}}) - - r, _ = j.Parse("{ }") - assert(t, "empty-obj", r, map[string]any{}) - - r, _ = j.Parse(`{ "val": 1 }`) - assert(t, "val-obj", r, map[string]any{"val": float64(1)}) - - r, _ = j.Parse(`{"id": "$", "v": [ null, null] }`) - assert(t, "complex-obj", r, map[string]any{"id": "$", "v": []any{nil, nil}}) - - _, err = j.Parse(`{ "id": { "foo": { } } , }`) - if err == nil { - t.Error("expected error for trailing comma") - } - - r, _ = j.Parse(`{ "foo": { "goo": 3 } }`) - assert(t, "nested-num", r, map[string]any{"foo": map[string]any{"goo": float64(3)}}) - - r, _ = j.Parse("[\r\n0,\r\n1,\r\n2\r\n]") - assert(t, "crlf-arr", r, []any{float64(0), float64(1), float64(2)}) - - r, _ = j.Parse(`/* g */ { "foo": //f` + "\n" + `"bar" }`) - assert(t, "comments-mixed", r, map[string]any{"foo": "bar"}) - - r, _ = j.Parse("/* g\r\n */ { \"foo\": //f\n\"bar\" }") - assert(t, "comments-crlf", r, map[string]any{"foo": "bar"}) - - r, _ = j.Parse("/* g\n */ { \"foo\": //f\n\"bar\"\n}") - assert(t, "comments-lf", r, map[string]any{"foo": "bar"}) - - r, _ = j.Parse(`{ "key1": { "key11": [ "val111", "val112" ] }, "key2": [ { "key21": false, "key22": 221 }, null, [{}] ] }`) - assert(t, "complex", r, map[string]any{ - "key1": map[string]any{"key11": []any{"val111", "val112"}}, - "key2": []any{ - map[string]any{"key21": false, "key22": float64(221)}, - nil, - []any{map[string]any{}}, - }, - }) -} - -func TestUsePlugin(t *testing.T) { - j := makeJsonc() - result, err := j.Parse(`{"a": 1, "b": "hello"}`) - if err != nil { - t.Fatal(err) - } - m, ok := result.(map[string]any) - if !ok { - t.Fatalf("expected map, got %T", result) - } - assert(t, "plugin", m, map[string]any{"a": float64(1), "b": "hello"}) -} - -// TestAltGJsoncTag verifies the GrammarText setting {Rule:{Alt:{G:'jsonc'}}} -// tagged every alt installed by the jsonc plugin with 'jsonc'. -func TestAltGJsoncTag(t *testing.T) { - // Fresh instance with allowTrailingComma so pair/elem close alts survive - // the rule-exclude filter and can be inspected here. - jc := jsonic.Make() - if err := jc.Use(Jsonc, map[string]any{"allowTrailingComma": true}); err != nil { - t.Fatal(err) - } - - rsm := jc.RSM() - checks := []struct { - rule string - isOpen bool - tokSig string - }{ - {"val", true, "#ZZ"}, - {"pair", false, "#CA #CB"}, - {"elem", false, "#CA #CS"}, - } - - for _, c := range checks { - rs, ok := rsm[c.rule] - if !ok { - t.Errorf("rule %q missing", c.rule) - continue - } - alts := rs.Close - if c.isOpen { - alts = rs.Open - } - - found := false - for _, a := range alts { - if !strings.Contains(a.G, "jsonc") { - continue - } - // Match the alt introduced by this plugin by its group tag(s). - // We only need to confirm 'jsonc' is present on at least one alt - // per rule; more importantly, every alt tagged as coming from - // the plugin must carry 'jsonc'. - found = true - tags := strings.Split(a.G, ",") - has := false - for _, t := range tags { - if strings.TrimSpace(t) == "jsonc" { - has = true - break - } - } - if !has { - t.Errorf("rule %q alt missing 'jsonc' tag: g=%q", c.rule, a.G) - } - } - if !found { - t.Errorf("rule %q: no alt with 'jsonc' tag found", c.rule) - } - } -} diff --git a/jsonc-grammar.jsonic b/jsonc-grammar.jsonic deleted file mode 100644 index 092da2f..0000000 --- a/jsonc-grammar.jsonic +++ /dev/null @@ -1,34 +0,0 @@ -# JSONC Grammar Definition -# Parsed by a standard Jsonic instance and passed to jsonic.grammar() -# Extends standard JSON grammar with end-of-input value handling. - -{ - options: text: { lex: false } - options: number: { hex: false oct: false bin: false sep: null exclude: "@/^\\./" } - options: string: { chars: '"' multiChars: '' allowUnknown: false } - options: string: escape: { v: null } - options: map: { extend: false } - options: lex: { empty: false } - options: rule: { finish: false } - - rule: val: open: { - alts: [ - { s: '#ZZ' g: jsonc } - ] - inject: { append: true } - } - - rule: pair: close: { - alts: [ - { s: '#CA #CB' b: 1 g: comma } - ] - inject: {} - } - - rule: elem: close: { - alts: [ - { s: '#CA #CS' b: 1 g: comma } - ] - inject: {} - } -} diff --git a/package.json b/package.json index 47f2670..f92ed8d 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,18 @@ { - "name": "@jsonic/jsonc", - "version": "0.8.0", - "description": "This plugin allows the Jsonic JSON parser to support JSONC syntax.", + "name": "@jsonic/c", + "version": "0.1.0", + "description": "Jsonic plugin that parses C source into a concrete syntax tree, preserving macros and compiler extensions.", "author": "Richard Rodger (http://richardrodger.com)", "license": "MIT", - "main": "dist/jsonc.js", - "types": "dist/jsonc.d.ts", - "homepage": "https://github.com/jsonicjs/jsonc", - "repository": "github:jsonicjs/jsonc", + "main": "dist/c.js", + "types": "dist/c.d.ts", + "homepage": "https://github.com/jsonicjs/c", + "repository": "github:jsonicjs/c", "keywords": [ - "jsonc", - "json", - "comments", + "c", "parser", + "concrete-syntax-tree", + "cst", "jsonic" ], "scripts": { @@ -22,16 +22,19 @@ "watch": "tsc --build src test -w", "build": "node embed-grammar.js && tsc --build src test", "clean": "rm -rf dist dist-test node_modules yarn.lock package-lock.json", - "reset": "npm run clean && npm i && npm run build && npm test", - "repo-tag": "REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;", - "repo-publish": "npm run clean && npm i && npm run repo-publish-quick", - "repo-publish-quick": "npm run build && npm run test && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org " + "reset": "npm run clean && npm i && npm run build && npm test" }, "peerDependencies": { "jsonic": ">=2" }, + "dependencies": { + "@jsonic/path": "^2.1.0", + "@jsonic/directive": "^2.2.0", + "@jsonic/expr": "^2.2.0" + }, "devDependencies": { "@types/node": "25.6.0", + "jsonic": "^2.28.0", "typescript": "6.0.3" }, "files": [ diff --git a/src/c.ts b/src/c.ts new file mode 100644 index 0000000..4481810 --- /dev/null +++ b/src/c.ts @@ -0,0 +1,307 @@ +/* Copyright (c) 2026 Richard Rodger and contributors, MIT License */ + +// @jsonic/c — Jsonic plugin that parses C source into a concrete syntax +// tree, preserving macros and compiler extensions. +// +// First-slice scope: +// - Focused lex matchers (./matchers.ts) for whitespace, line +// continuation, comments, preprocessor directive boundaries, header +// names, identifiers (with keyword/typedef-name reclassification), +// integer/float/char/string literals, and punctuators. +// - SymbolTable + MacroTable installed on ctx.meta.cmeta for shared +// access from lex matchers and rule actions. +// - A coarse top-level grammar that splits the translation unit into +// external-declaration units terminated by `;` or by a brace-balanced +// block. Each unit captures its tokens verbatim. When the unit looks +// like `typedef ;` the trailing identifier is registered +// as a typedef-name in the symbol table — this is exactly what the +// identifier matcher needs to reclassify subsequent occurrences as +// TYPEDEF_NAME. +// +// Subsequent slices will refine each unit into the full C grammar +// (declarators, statements, expressions via @jsonic/expr, full +// preprocessor handling) without disturbing this foundation. + +import type { Jsonic, Rule, Context, RuleSpec, Token } from 'jsonic' +import { allMatchers } from './matchers.js' +import { makeCMeta, type CMeta } from './symbols.js' +import { + C23_KEYWORDS, + EXT_KEYWORDS, + PUNCTUATORS, + keywordTokenName, +} from './tokens.js' + +export interface COptions { + // Reserved for future flags (strict mode, dialect selection, etc.) +} + +// ---- AST types ------------------------------------------------------ + +export interface Span { start: number; end: number; line: number; col: number } + +export interface CTokenRef { + kind: 'token' + tname: string + src: string + span: Span +} + +export interface CNode { + kind: string + span: Span + children: Array + trivia: { leading: CTokenRef[]; trailing: CTokenRef[] } + [extra: string]: any +} + +function tokenSpan(tkn: Token): Span { + return { start: tkn.sI, end: tkn.sI + tkn.len, line: tkn.rI, col: tkn.cI } +} + +function tokenRef(tkn: Token): CTokenRef { + return { kind: 'token', tname: tkn.name, src: tkn.src, span: tokenSpan(tkn) } +} + +function makeNode(kind: string, startTkn?: Token): CNode { + return { + kind, + span: startTkn ? tokenSpan(startTkn) : { start: 0, end: 0, line: 1, col: 1 }, + children: [], + trivia: { leading: [], trailing: [] }, + } +} + +function getCMeta(ctx: Context): CMeta { + return (ctx.meta as any).cmeta as CMeta +} + +// ---- Plugin --------------------------------------------------------- + +const C: any = function C(jsonic: Jsonic, _options: COptions): void { + + // 1. Register punctuator token names with their fixed sources, and + // keyword token names. We disable jsonic's built-in fixed-token + // matcher so identifier boundaries (e.g. `int_value`) aren't broken + // by a `int` keyword cut. + const fixedTokens: Record = {} + for (const [name, src] of PUNCTUATORS) fixedTokens[name] = src + for (const kw of [...C23_KEYWORDS, ...EXT_KEYWORDS]) { + fixedTokens[keywordTokenName(kw)!] = kw + } + + jsonic.options({ + fixed: { lex: false, token: fixedTokens }, + space: { lex: false }, + line: { lex: false }, + text: { lex: false }, + number: { lex: false }, + string: { lex: false }, + comment: { lex: false }, + value: { lex: false }, + match: { lex: true }, + rule: { + start: 'translation_unit', + finish: false, + }, + }) + + const matchEntries: Record = {} + for (const m of allMatchers()) { + matchEntries[m.name] = { order: m.order, make: () => m.make() } + } + jsonic.options({ lex: { match: matchEntries as any } }) + + // Register all special token names so they have stable Tins. + for (const name of [ + 'ID', 'TYPEDEF_NAME', 'MACRO_NAME', + 'LIT_INT', 'LIT_FLOAT', 'LIT_CHAR', 'LIT_STRING', 'LIT_HEADER_NAME', + 'PP_HASH', 'PP_NEWLINE', 'PP_RAW', + 'TRIVIA_LINE_COMMENT', 'TRIVIA_BLOCK_COMMENT', 'TRIVIA_LINE_CONT', + ]) { + jsonic.token(name as any) + } + + // Install CMeta on ctx.meta before parsing. + jsonic.options({ + parse: { + prepare: { + cmeta: ((_jsonic: Jsonic, ctx: Context, meta?: any) => { + const m = ctx.meta as any + if (!m.cmeta) m.cmeta = makeCMeta() + if (meta && meta.cmeta) m.cmeta = meta.cmeta + }) as any, + }, + }, + }) + + // 2. Grammar. + // + // The translation unit holds a list of external_declaration nodes. + // extdecl_loop is the iterating rule that inherits translation_unit's + // node and accumulates children. Each external_declaration is itself + // an iteration over tokens (no helper sub-rule) — it appends one token + // per cycle to its own node and uses r.k for state that survives + // jsonic's r:-recursion (r.k is propagated, r.u is not). + + jsonic.rule('translation_unit', (rs: RuleSpec) => { + rs + .bo((rule: Rule) => { rule.node = makeNode('translation_unit') }) + .open([ + { s: ['#ZZ'], b: 1, g: 'tu-empty' }, + { p: 'extdecl_loop', g: 'tu-loop' }, + ]) + .close([ + { s: ['#ZZ'], g: 'tu-end' }, + ]) + }) + + // extdecl_loop iterates external_declaration units. Its r.node is the + // translation_unit node (inherited). bc pushes each completed child. + jsonic.rule('extdecl_loop', (rs: RuleSpec) => { + rs + .open([ + { p: 'external_declaration', g: 'loop-one' }, + ]) + .bc((rule: Rule) => { + const child = rule.child + if (child && child.node && child.node.kind === 'external_declaration') { + rule.node.children.push(child.node) + } + }) + .close([ + { s: ['#ZZ'], b: 1, g: 'loop-end' }, + { r: 'extdecl_loop', g: 'loop-more' }, + ]) + }) + + // external_declaration absorbs one token per iteration into its node, + // then either terminates (top-level `;` or closing `}` at depth 0) or + // recurses with r:'external_declaration'. State (token list, depth) + // travels via r.k since u is not propagated across r:. + // + // bo guards against reset on r: by checking r.node.kind. + jsonic.rule('external_declaration', (rs: RuleSpec) => { + rs + .bo((rule: Rule) => { + if (!rule.node || rule.node.kind !== 'external_declaration') { + rule.node = makeNode('external_declaration') + } + if (!rule.k.tokens) rule.k.tokens = [] + if (rule.k.depth === undefined) rule.k.depth = 0 + if (rule.k.terminated === undefined) rule.k.terminated = false + }) + .open([ + // Terminate on EOF without consuming. + { s: ['#ZZ'], b: 1, g: 'extdecl-eof' }, + // Otherwise consume any single token. + { + s: [anyTokenSet(jsonic)], + a: (rule: Rule) => { + // The matched token lives in rule.o0 once the open-state alt + // has fired; ctx.t0 at this point is the next lookahead token. + const tkn = rule.o0 as Token + rule.k.tokens.push(tkn) + rule.node.children.push(tokenRef(tkn)) + if (tkn.name === 'PUNC_LBRACE') rule.k.depth++ + else if (tkn.name === 'PUNC_RBRACE') { + rule.k.depth-- + if (rule.k.depth <= 0) rule.k.terminated = true + } + else if (tkn.name === 'PUNC_SEMI' && rule.k.depth === 0) { + rule.k.terminated = true + } + }, + g: 'extdecl-tok', + }, + ]) + .close([ + // EOF — wrap up. + { + s: ['#ZZ'], + b: 1, + a: (rule: Rule, ctx: Context) => { + registerTypedefIfApplicable(rule.k.tokens as Token[], ctx) + }, + g: 'extdecl-finish-eof', + }, + // Hit terminator — wrap up and pop back to extdecl_loop. + { + c: (rule: Rule) => rule.k.terminated === true, + a: (rule: Rule, ctx: Context) => { + registerTypedefIfApplicable(rule.k.tokens as Token[], ctx) + }, + g: 'extdecl-finish', + }, + // Continue absorbing. + { r: 'external_declaration', g: 'extdecl-more' }, + ]) + }) +} + +C.defaults = {} as any + +// ---- Helpers -------------------------------------------------------- + +// Set of every token tin we want one_token to accept. We compute it lazily +// on first call (after token registration is complete). +let _anyTokenSetCache: number[] | null = null +function anyTokenSet(jsonic: Jsonic): number[] { + if (_anyTokenSetCache) return _anyTokenSetCache + const names: string[] = [ + 'ID', 'TYPEDEF_NAME', 'MACRO_NAME', + 'LIT_INT', 'LIT_FLOAT', 'LIT_CHAR', 'LIT_STRING', 'LIT_HEADER_NAME', + 'PP_HASH', 'PP_NEWLINE', 'PP_RAW', + 'TRIVIA_LINE_COMMENT', 'TRIVIA_BLOCK_COMMENT', 'TRIVIA_LINE_CONT', + ] + for (const [pn] of PUNCTUATORS) names.push(pn) + for (const kw of [...C23_KEYWORDS, ...EXT_KEYWORDS]) names.push(keywordTokenName(kw)!) + _anyTokenSetCache = names.map((n) => jsonic.token(n as any) as unknown as number) + return _anyTokenSetCache +} + +function registerTypedefIfApplicable(tokens: Token[], ctx: Context): void { + // Strip trivia. + const filtered = tokens.filter( + (t) => + t.name !== 'TRIVIA_LINE_COMMENT' && + t.name !== 'TRIVIA_BLOCK_COMMENT' && + t.name !== 'TRIVIA_LINE_CONT' && + t.name !== '#SP', + ) + if (filtered.length < 3) return + if (filtered[0].name !== 'KW_TYPEDEF') return + const last = filtered[filtered.length - 1] + if (last.name !== 'PUNC_SEMI') return + let i = filtered.length - 2 + if (filtered[i].name === 'ID' || filtered[i].name === 'TYPEDEF_NAME') { + const name = filtered[i].src + const cmeta = getCMeta(ctx) + cmeta.symbols.bindTypedef(name) + // Reclassify any already-lexed lookahead tokens that match this + // typedef name. Pre-fetched tokens live in ctx.t (the parser + // lookahead) and ctx.lex.pnt.token (the lexer queue). Mutating tin + // and name in place keeps subsequent grammar matches consistent + // with the freshly-registered typedef. + reclassifyAsTypedef(ctx, name) + } +} + +function reclassifyAsTypedef(ctx: Context, name: string): void { + const lex = (ctx as any).lex + if (!lex) return + const idTin = (ctx.cfg as any).t['ID'] + const tdTin = (ctx.cfg as any).t['TYPEDEF_NAME'] + const fix = (tkn: any) => { + if (!tkn || !tkn.isToken) return + if (tkn.tin === idTin && tkn.src === name) { + tkn.tin = tdTin + tkn.name = 'TYPEDEF_NAME' + } + } + if (Array.isArray(ctx.t)) for (const tkn of ctx.t) fix(tkn) + if (lex.pnt && Array.isArray(lex.pnt.token)) for (const tkn of lex.pnt.token) fix(tkn) +} + +export { C } +export default C diff --git a/src/jsonc.ts b/src/jsonc.ts deleted file mode 100644 index 00d0cb8..0000000 --- a/src/jsonc.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2021-2025 Richard Rodger, MIT License */ - -// Import Jsonic types used by plugin. -import { Jsonic } from 'jsonic' - -type JsoncOptions = { - allowTrailingComma?: boolean - disallowComments?: boolean -} - -// --- BEGIN EMBEDDED jsonc-grammar.jsonic --- -const grammarText = ` -# JSONC Grammar Definition -# Parsed by a standard Jsonic instance and passed to jsonic.grammar() -# Extends standard JSON grammar with end-of-input value handling. - -{ - options: text: { lex: false } - options: number: { hex: false oct: false bin: false sep: null exclude: "@/^\\\\./" } - options: string: { chars: '"' multiChars: '' allowUnknown: false } - options: string: escape: { v: null } - options: map: { extend: false } - options: lex: { empty: false } - options: rule: { finish: false } - - rule: val: open: { - alts: [ - { s: '#ZZ' g: jsonc } - ] - inject: { append: true } - } - - rule: pair: close: { - alts: [ - { s: '#CA #CB' b: 1 g: comma } - ] - inject: {} - } - - rule: elem: close: { - alts: [ - { s: '#CA #CS' b: 1 g: comma } - ] - inject: {} - } -} -` -// --- END EMBEDDED jsonc-grammar.jsonic --- - -function Jsonc(jsonic: Jsonic, options: JsoncOptions) { - const comment_lex = true !== options.disallowComments - const rule_exclude = options.allowTrailingComma ? '' : 'comma' - - // Apply grammar: static options and val ZZ rule alt. - jsonic.grammar(Jsonic.make()(grammarText), { rule: { alt: { g: 'jsonc' } } }) - - // Runtime options that depend on plugin arguments. - jsonic.options({ - comment: { - lex: comment_lex, - }, - rule: { - include: 'jsonc,json', - exclude: rule_exclude, - }, - }) -} - -export { Jsonc } - -export type { JsoncOptions } diff --git a/src/matchers.ts b/src/matchers.ts new file mode 100644 index 0000000..75d56f7 --- /dev/null +++ b/src/matchers.ts @@ -0,0 +1,508 @@ +/* Copyright (c) 2026 Richard Rodger and contributors, MIT License */ + +// Focused lex matchers for the C parser. Each matcher does one job and +// returns either a Token or undefined (signalling "not my prefix"). +// +// All matchers share access to the symbol/macro/mode state via +// ctx.meta.cmeta; see ./symbols.ts for the shape. +// +// Matcher contract (jsonic LexMatcher): +// (lex, rule, tI?) => Token | undefined +// On a hit: +// - Call lex.token(name, val, src) to construct the Token. +// - Advance lex.pnt.sI / rI / cI by the consumed length. + +import type { Lex, Rule, Token } from 'jsonic' +import { + C23_KEYWORDS, + EXT_KEYWORDS, + PUNCTUATORS, + keywordTokenName, +} from './tokens.js' +import type { CMeta } from './symbols.js' + +const RESERVED = new Set([...C23_KEYWORDS, ...EXT_KEYWORDS]) + +// Helpers -------------------------------------------------------------- + +function getMeta(lex: Lex): CMeta { + return (lex.ctx.meta as any).cmeta as CMeta +} + +function source(lex: Lex): string { + return lex.ctx.src() +} + +// Advance the lex point by `len` characters, updating row/col counters. +function advance(lex: Lex, src: string, len: number): void { + const pnt = lex.pnt + for (let i = 0; i < len; i++) { + const c = src.charCodeAt(pnt.sI + i) + if (c === 10) { // \n + pnt.rI++ + pnt.cI = 1 + } else { + pnt.cI++ + } + } + pnt.sI += len +} + +// Build a token, then advance the point. lex.token captures the current +// pnt at construction, so positions reflect the start of the token. +function emit( + lex: Lex, + name: string, + val: any, + src: string, + consumed: number, +): Token { + const tkn = lex.token(name as any, val, src) + advance(lex, source(lex), consumed) + return tkn +} + +// Whitespace ------------------------------------------------------------ +// C whitespace excludes newline when we are inside a preprocessor directive +// (newline terminates the directive). Outside directives newline is just +// space. + +export function makeWhitespaceMatcher() { + return function whitespace(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + if (sI >= src.length) return undefined + const c0 = src.charCodeAt(sI) + // Quick reject: only spaces, tabs, vertical tab, form feed, CR, LF. + if (c0 !== 32 && c0 !== 9 && c0 !== 11 && c0 !== 12 && c0 !== 13 && c0 !== 10) { + return undefined + } + const meta = getMeta(lex) + let i = sI + while (i < src.length) { + const c = src.charCodeAt(i) + if (c === 32 || c === 9 || c === 11 || c === 12 || c === 13) { + i++ + continue + } + if (c === 10) { + if (meta.mode.inDirective) break // newline ends a directive + i++ + continue + } + break + } + if (i === sI) return undefined + // Emit as a space token jsonic will treat as ignorable; we use the + // built-in '#SP' machinery here by returning undefined? No — we want to + // preserve trivia. Instead emit an ignored token with our own name. + return emit(lex, '#SP', src.substring(sI, i), src.substring(sI, i), i - sI) + } +} + +// Line continuation (backslash + newline) ------------------------------ +// In C this is logical-line splicing performed by the preprocessor before +// tokenisation. We treat it as trivia so it survives in the CST. + +export function makeLineContMatcher() { + return function lineCont(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + if (src.charCodeAt(sI) !== 92 /* \ */) return undefined + let consumed = 0 + if (src.charCodeAt(sI + 1) === 10) consumed = 2 + else if (src.charCodeAt(sI + 1) === 13 && src.charCodeAt(sI + 2) === 10) consumed = 3 + else if (src.charCodeAt(sI + 1) === 13) consumed = 2 + else return undefined + const text = src.substring(sI, sI + consumed) + return emit(lex, 'TRIVIA_LINE_CONT', text, text, consumed) + } +} + +// Line comment // ... --------------------------------------------------- + +export function makeLineCommentMatcher() { + return function lineComment(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + if (src.charCodeAt(sI) !== 47 /* / */) return undefined + if (src.charCodeAt(sI + 1) !== 47) return undefined + let i = sI + 2 + while (i < src.length) { + const c = src.charCodeAt(i) + if (c === 10 || c === 13) break + i++ + } + const text = src.substring(sI, i) + return emit(lex, 'TRIVIA_LINE_COMMENT', text, text, i - sI) + } +} + +// Block comment /* ... */ ---------------------------------------------- + +export function makeBlockCommentMatcher() { + return function blockComment(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + if (src.charCodeAt(sI) !== 47 /* / */) return undefined + if (src.charCodeAt(sI + 1) !== 42 /* * */) return undefined + let i = sI + 2 + while (i < src.length - 1) { + if (src.charCodeAt(i) === 42 && src.charCodeAt(i + 1) === 47) { + i += 2 + const text = src.substring(sI, i) + return emit(lex, 'TRIVIA_BLOCK_COMMENT', text, text, i - sI) + } + i++ + } + return lex.bad('unterminated_comment', sI, src.length) + } +} + +// Preprocessor directive opener ---------------------------------------- +// Emits PP_HASH only when '#' (or '%:') appears at the start of a logical +// line — i.e. preceded only by whitespace since the last unspliced newline. + +function atLineStart(src: string, sI: number): boolean { + let i = sI - 1 + while (i >= 0) { + const c = src.charCodeAt(i) + if (c === 10) return true + if (c === 32 || c === 9) { i--; continue } + if (c === 13) return true + return false + } + return true +} + +export function makePPDirectiveOpenerMatcher() { + return function ppDirective(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + const c0 = src.charCodeAt(sI) + let consumed = 0 + if (c0 === 35 /* # */) { + consumed = 1 + } else if (c0 === 37 /* % */ && src.charCodeAt(sI + 1) === 58 /* : */) { + consumed = 2 + } else { + return undefined + } + if (!atLineStart(src, sI)) return undefined + const meta = getMeta(lex) + meta.mode.inDirective = true + meta.mode.directiveName = null + meta.mode.expectHeaderName = false + const text = src.substring(sI, sI + consumed) + return emit(lex, 'PP_HASH', text, text, consumed) + } +} + +// Directive newline terminator ----------------------------------------- +// Emits PP_NEWLINE only when in directive mode; resets mode flags. + +export function makePPNewlineMatcher() { + return function ppNewline(lex: Lex, _rule: Rule): Token | undefined { + const meta = getMeta(lex) + if (!meta.mode.inDirective) return undefined + const src = source(lex) + const sI = lex.pnt.sI + const c0 = src.charCodeAt(sI) + if (c0 !== 10 && c0 !== 13) return undefined + let consumed = 1 + if (c0 === 13 && src.charCodeAt(sI + 1) === 10) consumed = 2 + meta.mode.inDirective = false + meta.mode.directiveName = null + meta.mode.expectHeaderName = false + const text = src.substring(sI, sI + consumed) + return emit(lex, 'PP_NEWLINE', text, text, consumed) + } +} + +// Header name or "foo.h" — only valid inside #include / #embed -- + +export function makeHeaderNameMatcher() { + return function headerName(lex: Lex, _rule: Rule): Token | undefined { + const meta = getMeta(lex) + if (!meta.mode.inDirective || !meta.mode.expectHeaderName) return undefined + const src = source(lex) + const sI = lex.pnt.sI + const c0 = src.charCodeAt(sI) + let close: number + if (c0 === 60 /* < */) close = 62 /* > */ + else if (c0 === 34 /* " */) close = 34 + else return undefined + let i = sI + 1 + while (i < src.length) { + const c = src.charCodeAt(i) + if (c === 10) return lex.bad('unterminated_header_name', sI, i) + if (c === close) { + i++ + meta.mode.expectHeaderName = false + const text = src.substring(sI, i) + return emit(lex, 'LIT_HEADER_NAME', text, text, i - sI) + } + i++ + } + return lex.bad('unterminated_header_name', sI, src.length) + } +} + +// Identifier (and keyword/typedef-name/macro-name reclassification) ---- + +const ID_RE = /^[A-Za-z_$][A-Za-z0-9_$]*/ + +export function makeIdentifierMatcher() { + return function identifier(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + const c0 = src.charCodeAt(sI) + // Fast reject: must start with letter, _, or $ (gcc allows $). + const isStart = + (c0 >= 65 && c0 <= 90) || + (c0 >= 97 && c0 <= 122) || + c0 === 95 || c0 === 36 + if (!isStart) return undefined + const m = ID_RE.exec(src.substring(sI)) + if (!m) return undefined + const word = m[0] + const meta = getMeta(lex) + + // Reserved word? + if (RESERVED.has(word)) { + const tname = keywordTokenName(word)! + // If we are in a directive and this is the first identifier, record + // the directive name and arm the header-name flag for include/embed. + if (meta.mode.inDirective && meta.mode.directiveName === null) { + meta.mode.directiveName = word + } + return emit(lex, tname, word, word, word.length) + } + + // Inside a directive, the first identifier names the directive. + if (meta.mode.inDirective && meta.mode.directiveName === null) { + meta.mode.directiveName = word + if (word === 'include' || word === 'embed' || word === 'include_next') { + meta.mode.expectHeaderName = true + } + // Common directives are not C reserved words; emit a normal ID and + // let the directive grammar dispatch on the value. + return emit(lex, 'ID', word, word, word.length) + } + + // Typedef-name disambiguation. A name in scope as a typedef becomes + // TYPEDEF_NAME; the parser uses this distinction to choose between + // declaration and expression alts. + // + // Note: we do NOT emit TYPEDEF_NAME inside directive bodies — there the + // name is just a token, semantics deferred. + if (!meta.mode.inDirective && meta.symbols.isTypedef(word)) { + return emit(lex, 'TYPEDEF_NAME', word, word, word.length) + } + + // Macro-name tagging is informational; we still emit ID so the grammar + // treats it like any other identifier. Downstream rule actions can + // consult ctx.meta.cmeta.macros to set call_expr.isMacro. + return emit(lex, 'ID', word, word, word.length) + } +} + +// Integer literal ------------------------------------------------------ +// dec, hex, oct, binary, with C23 ' digit separators and integer suffixes +// (u/U, l/L, ll/LL, wb/WB, plus combinations). + +const INT_RE = new RegExp( + '^(' + + '0[xX][0-9a-fA-F](?:[\'0-9a-fA-F])*' + // hex + '|0[bB][01](?:[\'01])*' + // binary (C23) + '|0(?:[\'0-7])*' + // octal (also matches lone 0) + '|[1-9](?:[\'0-9])*' + // decimal + ')([uUlL]*[wWbBzZ]*[uUlL]*)?', +) + +export function makeIntegerMatcher() { + return function integer(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + const c0 = src.charCodeAt(sI) + if (c0 < 48 || c0 > 57) return undefined + const rest = src.substring(sI) + const m = INT_RE.exec(rest) + if (!m) return undefined + // Disambiguate from float: if the next char after the integer part is + // '.', 'e', 'E', 'p', 'P', defer to the float matcher. + const after = rest.charCodeAt(m[0].length) + if (after === 46 /* . */ || after === 101 /* e */ || after === 69 /* E */) { + // For hex literals only p/P signals exponent. + if (m[1].startsWith('0x') || m[1].startsWith('0X')) { + // hex without . or p in m[1]: a trailing 'e' is not a float exponent + // (it could be a hex digit), so we keep the int. + } else { + return undefined + } + } + if ((m[1].startsWith('0x') || m[1].startsWith('0X')) && + (after === 46 || after === 112 /* p */ || after === 80 /* P */)) { + return undefined + } + const text = m[0] + return emit(lex, 'LIT_INT', text, text, text.length) + } +} + +// Floating literal ----------------------------------------------------- + +const FLOAT_DEC_RE = new RegExp( + '^(?:' + + '(?:[0-9](?:[\'0-9])*)?\\.[0-9](?:[\'0-9])*(?:[eE][+-]?[0-9](?:[\'0-9])*)?' + + '|[0-9](?:[\'0-9])*\\.(?:[eE][+-]?[0-9](?:[\'0-9])*)?' + + '|[0-9](?:[\'0-9])*[eE][+-]?[0-9](?:[\'0-9])*' + + ')[fFlLdD]?[fFlL]?', +) + +const FLOAT_HEX_RE = new RegExp( + '^0[xX](?:' + + '[0-9a-fA-F](?:[\'0-9a-fA-F])*\\.(?:[0-9a-fA-F](?:[\'0-9a-fA-F])*)?' + + '|\\.[0-9a-fA-F](?:[\'0-9a-fA-F])*' + + '|[0-9a-fA-F](?:[\'0-9a-fA-F])*' + + ')[pP][+-]?[0-9](?:[\'0-9])*[fFlL]?', +) + +export function makeFloatMatcher() { + return function float(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + const c0 = src.charCodeAt(sI) + // Must start with digit or '.' followed by digit. + const c1 = src.charCodeAt(sI + 1) + const startsDigit = c0 >= 48 && c0 <= 57 + const startsDot = c0 === 46 && c1 >= 48 && c1 <= 57 + if (!startsDigit && !startsDot) return undefined + const rest = src.substring(sI) + let m = FLOAT_HEX_RE.exec(rest) + if (!m) m = FLOAT_DEC_RE.exec(rest) + if (!m) return undefined + // Reject pure integers without dot, exponent or float suffix; let the + // integer matcher take them. + const text = m[0] + if (!/[.eEpPfFlL]/.test(text) && !text.startsWith('0x') && !text.startsWith('0X')) { + return undefined + } + return emit(lex, 'LIT_FLOAT', text, text, text.length) + } +} + +// Character literal ---------------------------------------------------- + +const CHAR_PREFIX_RE = /^(L|u8|u|U)?'/ + +export function makeCharLiteralMatcher() { + return function charLit(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + const rest = src.substring(sI) + const pm = CHAR_PREFIX_RE.exec(rest) + if (!pm) return undefined + let i = sI + pm[0].length + while (i < src.length) { + const c = src.charCodeAt(i) + if (c === 10) return lex.bad('unterminated_char', sI, i) + if (c === 92 /* \ */) { i += 2; continue } + if (c === 39 /* ' */) { + i++ + const text = src.substring(sI, i) + return emit(lex, 'LIT_CHAR', text, text, i - sI) + } + i++ + } + return lex.bad('unterminated_char', sI, src.length) + } +} + +// String literal ------------------------------------------------------- +// Encoding-prefixes: u8, u, U, L. Raw strings (R"...") are a C++ feature +// that some compilers extend to C; supported as an extension. + +const STR_PREFIX_RE = /^(u8|u|U|L)?(R)?"/ + +export function makeStringLiteralMatcher() { + return function stringLit(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + const rest = src.substring(sI) + const pm = STR_PREFIX_RE.exec(rest) + if (!pm) return undefined + const isRaw = pm[2] === 'R' + let i = sI + pm[0].length + if (isRaw) { + // R"delim(...)delim" + let delimEnd = i + while (delimEnd < src.length && src.charCodeAt(delimEnd) !== 40 /* ( */) { + delimEnd++ + } + if (delimEnd >= src.length) return lex.bad('unterminated_string', sI, src.length) + const delim = src.substring(i, delimEnd) + const closer = ')' + delim + '"' + const close = src.indexOf(closer, delimEnd + 1) + if (close < 0) return lex.bad('unterminated_string', sI, src.length) + const end = close + closer.length + const text = src.substring(sI, end) + return emit(lex, 'LIT_STRING', text, text, end - sI) + } + while (i < src.length) { + const c = src.charCodeAt(i) + if (c === 10) return lex.bad('unterminated_string', sI, i) + if (c === 92 /* \ */) { i += 2; continue } + if (c === 34 /* " */) { + i++ + const text = src.substring(sI, i) + return emit(lex, 'LIT_STRING', text, text, i - sI) + } + i++ + } + return lex.bad('unterminated_string', sI, src.length) + } +} + +// Punctuator dispatch -------------------------------------------------- +// One matcher; tries longest-first against the punctuator catalog. + +export function makePunctuatorMatcher() { + // Pre-sort once, longest source first. + const sorted = [...PUNCTUATORS].sort((a, b) => b[1].length - a[1].length) + return function punctuator(lex: Lex, _rule: Rule): Token | undefined { + const src = source(lex) + const sI = lex.pnt.sI + for (const [name, p] of sorted) { + let ok = true + for (let i = 0; i < p.length; i++) { + if (src.charCodeAt(sI + i) !== p.charCodeAt(i)) { ok = false; break } + } + if (ok) { + return emit(lex, name, p, p, p.length) + } + } + return undefined + } +} + +// All matchers, ordered. Lower order = tried first. +// jsonic dispatches by ascending order; we want trivia and special-mode +// matchers to win against generic ones. +export function allMatchers(): Array<{ name: string; order: number; make: () => any }> { + return [ + { name: 'c_line_cont', order: 100, make: () => makeLineContMatcher() }, + { name: 'c_block_comment', order: 110, make: () => makeBlockCommentMatcher() }, + { name: 'c_line_comment', order: 120, make: () => makeLineCommentMatcher() }, + { name: 'c_pp_newline', order: 130, make: () => makePPNewlineMatcher() }, + { name: 'c_pp_open', order: 140, make: () => makePPDirectiveOpenerMatcher() }, + { name: 'c_header_name', order: 150, make: () => makeHeaderNameMatcher() }, + { name: 'c_whitespace', order: 160, make: () => makeWhitespaceMatcher() }, + { name: 'c_string', order: 200, make: () => makeStringLiteralMatcher() }, + { name: 'c_char', order: 210, make: () => makeCharLiteralMatcher() }, + { name: 'c_float', order: 220, make: () => makeFloatMatcher() }, + { name: 'c_int', order: 230, make: () => makeIntegerMatcher() }, + { name: 'c_identifier', order: 240, make: () => makeIdentifierMatcher() }, + { name: 'c_punctuator', order: 900, make: () => makePunctuatorMatcher() }, + ] +} diff --git a/src/symbols.ts b/src/symbols.ts new file mode 100644 index 0000000..d0cc118 --- /dev/null +++ b/src/symbols.ts @@ -0,0 +1,165 @@ +/* Copyright (c) 2026 Richard Rodger and contributors, MIT License */ + +// Symbol and macro tables used by the C parser to resolve the classic +// identifier/typedef-name disambiguation problem. +// +// Both tables live on Context.meta so lex matchers and rule actions can read +// and mutate the same instance. The identifier-classification matcher +// consults SymbolTable.isTypedef(name) before deciding whether to emit +// ID or TYPEDEF_NAME, and consults MacroTable.has(name) to optionally +// emit MACRO_NAME (which the grammar still treats as ID for syntax but +// tags downstream so call_expr.isMacro can be set). +// +// Scopes form a stack; the parser pushes/pops on: +// - file (root, never popped) +// - function-prototype (function declarator with parameter list) +// - function-body (the compound-statement of a function definition) +// - block (compound-statement) +// - struct-or-union (member declaration list) +// - enum (enumerator list) +// - for-init (the init clause of a for loop, C99+) +// +// Inner scopes shadow outer ones; lookups walk the stack outward. + +export type ScopeKind = + | 'file' + | 'fn-proto' + | 'fn-body' + | 'block' + | 'struct-union' + | 'enum' + | 'for-init' + +export interface Scope { + kind: ScopeKind + // Names bound in this scope to their kind. We track typedef-ness primarily; + // ordinary identifiers (variables, functions, enumerators) are recorded so + // that an inner non-typedef declaration of the same name correctly hides an + // outer typedef. + bind: Map + // Tags (struct/union/enum names) live in a separate namespace in C. + tags: Map +} + +export class SymbolTable { + private stack: Scope[] = [{ + kind: 'file', + bind: new Map(), + tags: new Map(), + }] + + enter(kind: ScopeKind): void { + this.stack.push({ kind, bind: new Map(), tags: new Map() }) + } + + exit(): void { + if (this.stack.length <= 1) return // never pop the file scope + this.stack.pop() + } + + depth(): number { + return this.stack.length + } + + current(): Scope { + return this.stack[this.stack.length - 1] + } + + // True if `name` resolves to a typedef-name in any visible scope, with + // the innermost binding winning. + isTypedef(name: string): boolean { + for (let i = this.stack.length - 1; i >= 0; i--) { + const b = this.stack[i].bind.get(name) + if (b !== undefined) return b === 'typedef' + } + return false + } + + // True if `name` is bound at all (typedef or ordinary). + isBound(name: string): boolean { + for (let i = this.stack.length - 1; i >= 0; i--) { + if (this.stack[i].bind.has(name)) return true + } + return false + } + + bindTypedef(name: string): void { + this.current().bind.set(name, 'typedef') + } + + bindOrdinary(name: string): void { + this.current().bind.set(name, 'ordinary') + } + + bindTag(name: string, kind: 'struct' | 'union' | 'enum'): void { + this.current().tags.set(name, kind) + } + + hasTag(name: string): boolean { + for (let i = this.stack.length - 1; i >= 0; i--) { + if (this.stack[i].tags.has(name)) return true + } + return false + } +} + +// Macro definitions captured from #define directives. We do not expand; +// we only need to know which names are macros so call sites can be tagged. +export interface MacroDef { + name: string + isFunctionLike: boolean + params?: string[] // present iff isFunctionLike + variadic?: boolean // ... in parameter list + // Body is preserved as a raw token sequence on the AST node; we only need + // names here. +} + +export class MacroTable { + private defs = new Map() + + define(def: MacroDef): void { + this.defs.set(def.name, def) + } + + undefine(name: string): void { + this.defs.delete(name) + } + + has(name: string): boolean { + return this.defs.has(name) + } + + get(name: string): MacroDef | undefined { + return this.defs.get(name) + } +} + +// Lex-mode flags that ride on Context.meta. Lex matchers read these to know +// whether to enter directive-line mode (where newline becomes a token and +// header-name forms are valid) or normal mode. +export interface LexMode { + // True between the start-of-logical-line `#` and the terminating newline. + inDirective: boolean + // True when the next token inside a directive should be parsed as a + // header-name (set by the #include matcher upon seeing `include`). + expectHeaderName: boolean + // The directive name currently being parsed, or null. Used by matchers + // that need to know which directive they are inside. + directiveName: string | null +} + +// All C-parser global state lives here, accessible from any matcher or rule +// via ctx.meta.cmeta. +export interface CMeta { + symbols: SymbolTable + macros: MacroTable + mode: LexMode +} + +export function makeCMeta(): CMeta { + return { + symbols: new SymbolTable(), + macros: new MacroTable(), + mode: { inDirective: false, expectHeaderName: false, directiveName: null }, + } +} diff --git a/src/tokens.ts b/src/tokens.ts new file mode 100644 index 0000000..fc9b534 --- /dev/null +++ b/src/tokens.ts @@ -0,0 +1,201 @@ +/* Copyright (c) 2026 Richard Rodger and contributors, MIT License */ + +// Token name catalog for the C concrete-syntax parser. +// +// Every token a C source can produce gets a stable name here. Lex matchers +// resolve names to tins (token integers) via lex.tokenize(name) and emit +// tokens carrying these names. Grammar rules reference the same names. +// +// Naming convention: +// PUNC_* punctuators and operators (one token per literal form) +// KW_* keywords (C23 + extension keywords) +// LIT_* literals (integer, float, char, string, header-name) +// ID ordinary identifier +// TYPEDEF_NAME identifier currently registered as a typedef in scope +// MACRO_NAME identifier currently registered as a macro +// PP_* preprocessor markers +// TRIVIA_* preserved trivia (comments, whitespace if captured) + + +// ---- C23 keywords ---- +// Pulled from N3096 §6.4.1 plus C23 additions (alignas/alignof/bool/false/ +// nullptr/static_assert/thread_local/true/typeof/typeof_unqual and the +// underscore-prefixed legacy spellings). +export const C23_KEYWORDS: string[] = [ + 'auto', 'break', 'case', 'char', 'const', 'constexpr', 'continue', + 'default', 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', + 'goto', 'if', 'inline', 'int', 'long', 'register', 'restrict', 'return', + 'short', 'signed', 'sizeof', 'static', 'struct', 'switch', + 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while', + + // C23 unprefixed + 'alignas', 'alignof', 'bool', 'false', 'nullptr', + 'static_assert', 'thread_local', 'true', + 'typeof', 'typeof_unqual', + + // Underscore-prefixed (still valid in C23) + '_Alignas', '_Alignof', '_Atomic', '_BitInt', '_Bool', '_Complex', + '_Decimal32', '_Decimal64', '_Decimal128', + '_Generic', '_Imaginary', '_Noreturn', '_Static_assert', + '_Thread_local', +] + +// ---- Compiler extension keywords ---- +// GCC, Clang, MSVC. Recognized as keywords so the grammar can place them. +export const EXT_KEYWORDS: string[] = [ + // GCC / Clang + '__attribute__', '__attribute', + '__asm__', '__asm', 'asm', + '__inline__', '__inline', + '__signed__', '__signed', + '__volatile__', '__volatile', + '__const__', '__const', + '__restrict__', '__restrict', + '__typeof__', '__typeof', + '__alignof__', '__alignof', + '__extension__', + '__label__', + '__thread', + '__auto_type', + '__builtin_va_arg', '__builtin_va_list', '__builtin_offsetof', + '__builtin_choose_expr', '__builtin_types_compatible_p', + '__real__', '__imag__', + '__complex__', + '__func__', '__FUNCTION__', '__PRETTY_FUNCTION__', + + // MSVC + '__declspec', + '__cdecl', '__stdcall', '__fastcall', '__thiscall', '__vectorcall', + '__forceinline', + '__int8', '__int16', '__int32', '__int64', + '__ptr32', '__ptr64', + '__unaligned', + '__w64', + '__pragma', + + // Clang + '_Nonnull', '_Nullable', '_Null_unspecified', +] + +// ---- Punctuators ---- +// (name, source). A separate token per literal form keeps lex matchers tiny +// and makes grammar rules readable. Order matters for longest-match in the +// dispatcher: longer forms first within a same-prefix group. +export const PUNCTUATORS: Array<[string, string]> = [ + // 4-char + ['PUNC_ELLIPSIS', '...'], + + // 3-char + ['PUNC_LSHIFT_ASSIGN', '<<='], + ['PUNC_RSHIFT_ASSIGN', '>>='], + ['PUNC_HASH_HASH_ALT', '%:%:'], + + // 2-char + ['PUNC_ARROW', '->'], + ['PUNC_PLUS_PLUS', '++'], + ['PUNC_MINUS_MINUS', '--'], + ['PUNC_LSHIFT', '<<'], + ['PUNC_RSHIFT', '>>'], + ['PUNC_LE', '<='], + ['PUNC_GE', '>='], + ['PUNC_EQ', '=='], + ['PUNC_NE', '!='], + ['PUNC_AND_AND', '&&'], + ['PUNC_OR_OR', '||'], + ['PUNC_PLUS_ASSIGN', '+='], + ['PUNC_MINUS_ASSIGN', '-='], + ['PUNC_STAR_ASSIGN', '*='], + ['PUNC_SLASH_ASSIGN', '/='], + ['PUNC_PERCENT_ASSIGN', '%='], + ['PUNC_AMP_ASSIGN', '&='], + ['PUNC_CARET_ASSIGN', '^='], + ['PUNC_PIPE_ASSIGN', '|='], + ['PUNC_HASH_HASH', '##'], + // C digraphs / alt-tokens + ['PUNC_LBRACKET_ALT', '<:'], + ['PUNC_RBRACKET_ALT', ':>'], + ['PUNC_LBRACE_ALT', '<%'], + ['PUNC_RBRACE_ALT', '%>'], + ['PUNC_HASH_ALT', '%:'], + // C23 attribute brackets are [[ and ]] which we keep as two LBRACKETs; + // grammar reassembles them from a [ [ pair in attribute context. + + // 1-char + ['PUNC_LPAREN', '('], + ['PUNC_RPAREN', ')'], + ['PUNC_LBRACE', '{'], + ['PUNC_RBRACE', '}'], + ['PUNC_LBRACKET', '['], + ['PUNC_RBRACKET', ']'], + ['PUNC_SEMI', ';'], + ['PUNC_COMMA', ','], + ['PUNC_DOT', '.'], + ['PUNC_QUESTION', '?'], + ['PUNC_COLON', ':'], + ['PUNC_ASSIGN', '='], + ['PUNC_PLUS', '+'], + ['PUNC_MINUS', '-'], + ['PUNC_STAR', '*'], + ['PUNC_SLASH', '/'], + ['PUNC_PERCENT', '%'], + ['PUNC_AMP', '&'], + ['PUNC_PIPE', '|'], + ['PUNC_CARET', '^'], + ['PUNC_TILDE', '~'], + ['PUNC_BANG', '!'], + ['PUNC_LT', '<'], + ['PUNC_GT', '>'], + ['PUNC_HASH', '#'], + ['PUNC_AT', '@'], // not standard C; some extensions use it + ['PUNC_BACKSLASH', '\\'], // line-continuation already handled separately +] + +// ---- Token names not derived from punctuators or keywords ---- +export const SPECIAL_TOKENS: string[] = [ + 'ID', + 'TYPEDEF_NAME', + 'MACRO_NAME', + 'LIT_INT', + 'LIT_FLOAT', + 'LIT_CHAR', + 'LIT_STRING', + 'LIT_HEADER_NAME', // or "foo.h" inside #include + 'PP_HASH', // start-of-line # that opens a directive + 'PP_NEWLINE', // logical end-of-directive newline + 'PP_RAW', // opaque token within a directive body + 'TRIVIA_LINE_COMMENT', + 'TRIVIA_BLOCK_COMMENT', + 'TRIVIA_LINE_CONT', +] + +// ---- Helper: build a Set of all C identifier-like reserved words ---- +export const RESERVED_WORDS: Set = new Set([ + ...C23_KEYWORDS, + ...EXT_KEYWORDS, +]) + +// Returns canonical token name for a keyword, or null if not reserved. +export function keywordTokenName(word: string): string | null { + if (!RESERVED_WORDS.has(word)) return null + // KW_ with non-letters preserved as underscores. + return 'KW_' + word.replace(/[^A-Za-z0-9_]/g, '_').toUpperCase() +} + +// Full list of token names this parser uses, suitable for one-shot +// registration with jsonic.options({ fixed: { token: { ... } } }). +export function allTokenNamesAndSources(): Record { + const out: Record = {} + for (const [name, src] of PUNCTUATORS) { + out[name] = src + } + // keywords are matched as identifiers then reclassified, so they don't + // need a fixed src — but registering them lets grammar rules name them. + for (const kw of [...C23_KEYWORDS, ...EXT_KEYWORDS]) { + const name = keywordTokenName(kw)! + // Use the keyword spelling as the fixed src so jsonic can match it as a + // fixed token; the identifier matcher would still produce ID for non- + // reserved names. + out[name] = kw + } + return out +} diff --git a/test/JSONTestSuite/LICENSE b/test/JSONTestSuite/LICENSE deleted file mode 100644 index c4b3621..0000000 --- a/test/JSONTestSuite/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Nicolas Seriot - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/test/JSONTestSuite/README.md b/test/JSONTestSuite/README.md deleted file mode 100644 index 775ccfd..0000000 --- a/test/JSONTestSuite/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# JSON Parsing Test Suite -A comprehensive test suite for RFC 8259 compliant JSON parsers - -This repository was created as an appendix to the article [Parsing JSON is a Minefield 💣](http://seriot.ch/parsing_json.php). - -**/parsers/** - -This directory contains several parsers and tiny wrappers to turn the parsers into JSON validators, by returning a specific value. - -- `0` the parser did accept the content -- `1` the parser did reject the content -- `>1` the process did crash -- `timeout` happens after 5 seconds - -**/test\_parsing/** - -The name of these files tell if their contents should be accepted or rejected. - -- `y_` content must be accepted by parsers -- `n_` content must be rejected by parsers -- `i_` parsers are free to accept or reject content - -**/test\_transform/** - -These files contain weird structures and characters that parsers may understand differently, eg: - -- huge numbers -- dictionaries with similar keys -- NULL characters -- escaped invalid strings - -These files were used to produce `results/transform.html`. - -**/run_tests.py** - -Run all parsers with all files: - - $ python3 run_tests.py - -Run all parsers with a specific file: - - $ python3 run_tests.py file.json - -Run specific parsers with all files: - - $ echo '["Python 2.7.10", "Python 3.5.2"]' > python_only.json - $ python3 run_tests.py --filter=python_only.json - -The script writes logs in `results/logs.txt`. - -The script then reads `logs.txt` and generates `results/parsing.html`. - -**/results/** - -JSON Parsing Tests diff --git a/test/JSONTestSuite/test_parsing/i_number_double_huge_neg_exp.json b/test/JSONTestSuite/test_parsing/i_number_double_huge_neg_exp.json deleted file mode 100644 index ae4c7b7..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_double_huge_neg_exp.json +++ /dev/null @@ -1 +0,0 @@ -[123.456e-789] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_huge_exp.json b/test/JSONTestSuite/test_parsing/i_number_huge_exp.json deleted file mode 100644 index 9b5efa2..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_huge_exp.json +++ /dev/null @@ -1 +0,0 @@ -[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_neg_int_huge_exp.json b/test/JSONTestSuite/test_parsing/i_number_neg_int_huge_exp.json deleted file mode 100755 index 3abd58a..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_neg_int_huge_exp.json +++ /dev/null @@ -1 +0,0 @@ -[-1e+9999] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_pos_double_huge_exp.json b/test/JSONTestSuite/test_parsing/i_number_pos_double_huge_exp.json deleted file mode 100755 index e10a7eb..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_pos_double_huge_exp.json +++ /dev/null @@ -1 +0,0 @@ -[1.5e+9999] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_real_neg_overflow.json b/test/JSONTestSuite/test_parsing/i_number_real_neg_overflow.json deleted file mode 100644 index 3d628a9..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_real_neg_overflow.json +++ /dev/null @@ -1 +0,0 @@ -[-123123e100000] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_real_pos_overflow.json b/test/JSONTestSuite/test_parsing/i_number_real_pos_overflow.json deleted file mode 100644 index 54d7d3d..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_real_pos_overflow.json +++ /dev/null @@ -1 +0,0 @@ -[123123e100000] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_real_underflow.json b/test/JSONTestSuite/test_parsing/i_number_real_underflow.json deleted file mode 100644 index c5236eb..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_real_underflow.json +++ /dev/null @@ -1 +0,0 @@ -[123e-10000000] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_too_big_neg_int.json b/test/JSONTestSuite/test_parsing/i_number_too_big_neg_int.json deleted file mode 100644 index dfa3846..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_too_big_neg_int.json +++ /dev/null @@ -1 +0,0 @@ -[-123123123123123123123123123123] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_too_big_pos_int.json b/test/JSONTestSuite/test_parsing/i_number_too_big_pos_int.json deleted file mode 100644 index 338a8c3..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_too_big_pos_int.json +++ /dev/null @@ -1 +0,0 @@ -[100000000000000000000] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_number_very_big_negative_int.json b/test/JSONTestSuite/test_parsing/i_number_very_big_negative_int.json deleted file mode 100755 index e2d9738..0000000 --- a/test/JSONTestSuite/test_parsing/i_number_very_big_negative_int.json +++ /dev/null @@ -1 +0,0 @@ -[-237462374673276894279832749832423479823246327846] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_object_key_lone_2nd_surrogate.json b/test/JSONTestSuite/test_parsing/i_object_key_lone_2nd_surrogate.json deleted file mode 100644 index 5be7eba..0000000 --- a/test/JSONTestSuite/test_parsing/i_object_key_lone_2nd_surrogate.json +++ /dev/null @@ -1 +0,0 @@ -{"\uDFAA":0} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.json b/test/JSONTestSuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.json deleted file mode 100644 index 3b9e37c..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_1st_surrogate_but_2nd_missing.json +++ /dev/null @@ -1 +0,0 @@ -["\uDADA"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json b/test/JSONTestSuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json deleted file mode 100644 index 4875928..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_1st_valid_surrogate_2nd_invalid.json +++ /dev/null @@ -1 +0,0 @@ -["\uD888\u1234"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_UTF-16LE_with_BOM.json b/test/JSONTestSuite/test_parsing/i_string_UTF-16LE_with_BOM.json deleted file mode 100644 index 2a79c0629a49133d8f715bddbef19cfb3ef025bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12 ScmezWFPcG#;Uy5qG5`P~Km+3d diff --git a/test/JSONTestSuite/test_parsing/i_string_UTF-8_invalid_sequence.json b/test/JSONTestSuite/test_parsing/i_string_UTF-8_invalid_sequence.json deleted file mode 100755 index e2a968a..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_UTF-8_invalid_sequence.json +++ /dev/null @@ -1 +0,0 @@ -["日ш"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_UTF8_surrogate_U+D800.json b/test/JSONTestSuite/test_parsing/i_string_UTF8_surrogate_U+D800.json deleted file mode 100644 index 916bff9..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_UTF8_surrogate_U+D800.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_and_escape_valid.json b/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_and_escape_valid.json deleted file mode 100755 index 3cb11d2..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_and_escape_valid.json +++ /dev/null @@ -1 +0,0 @@ -["\uD800\n"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_pair.json b/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_pair.json deleted file mode 100755 index 38ec23b..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogate_pair.json +++ /dev/null @@ -1 +0,0 @@ -["\uDd1ea"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogates_escape_valid.json b/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogates_escape_valid.json deleted file mode 100755 index c9cd6f6..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_incomplete_surrogates_escape_valid.json +++ /dev/null @@ -1 +0,0 @@ -["\uD800\uD800\n"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_invalid_lonely_surrogate.json b/test/JSONTestSuite/test_parsing/i_string_invalid_lonely_surrogate.json deleted file mode 100755 index 3abbd8d..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_invalid_lonely_surrogate.json +++ /dev/null @@ -1 +0,0 @@ -["\ud800"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_invalid_surrogate.json b/test/JSONTestSuite/test_parsing/i_string_invalid_surrogate.json deleted file mode 100755 index ffddc04..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_invalid_surrogate.json +++ /dev/null @@ -1 +0,0 @@ -["\ud800abc"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_invalid_utf-8.json b/test/JSONTestSuite/test_parsing/i_string_invalid_utf-8.json deleted file mode 100644 index 8e45a7e..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_invalid_utf-8.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_inverted_surrogates_U+1D11E.json b/test/JSONTestSuite/test_parsing/i_string_inverted_surrogates_U+1D11E.json deleted file mode 100755 index 0d5456c..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_inverted_surrogates_U+1D11E.json +++ /dev/null @@ -1 +0,0 @@ -["\uDd1e\uD834"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_iso_latin_1.json b/test/JSONTestSuite/test_parsing/i_string_iso_latin_1.json deleted file mode 100644 index 9389c98..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_iso_latin_1.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_lone_second_surrogate.json b/test/JSONTestSuite/test_parsing/i_string_lone_second_surrogate.json deleted file mode 100644 index 1dbd397..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_lone_second_surrogate.json +++ /dev/null @@ -1 +0,0 @@ -["\uDFAA"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_lone_utf8_continuation_byte.json b/test/JSONTestSuite/test_parsing/i_string_lone_utf8_continuation_byte.json deleted file mode 100644 index 729337c..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_lone_utf8_continuation_byte.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_not_in_unicode_range.json b/test/JSONTestSuite/test_parsing/i_string_not_in_unicode_range.json deleted file mode 100644 index df90a29..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_not_in_unicode_range.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_2_bytes.json b/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_2_bytes.json deleted file mode 100644 index c8cee5e..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_2_bytes.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes.json b/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes.json deleted file mode 100755 index 9a91da7..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes_null.json b/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes_null.json deleted file mode 100755 index d24fffd..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_overlong_sequence_6_bytes_null.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_truncated-utf-8.json b/test/JSONTestSuite/test_parsing/i_string_truncated-utf-8.json deleted file mode 100644 index 63c7777..0000000 --- a/test/JSONTestSuite/test_parsing/i_string_truncated-utf-8.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_string_utf16BE_no_BOM.json b/test/JSONTestSuite/test_parsing/i_string_utf16BE_no_BOM.json deleted file mode 100644 index 57e5392ff6309134268c7e3ec2a9289b99ff7148..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10 PcmZRGW>8{y3B<7g33~zN diff --git a/test/JSONTestSuite/test_parsing/i_string_utf16LE_no_BOM.json b/test/JSONTestSuite/test_parsing/i_string_utf16LE_no_BOM.json deleted file mode 100644 index c49c1b25d8e5819591993d4d45e4649a46c1b3e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10 Pcma!MP-1uq#IXzj3t$1} diff --git a/test/JSONTestSuite/test_parsing/i_structure_500_nested_arrays.json b/test/JSONTestSuite/test_parsing/i_structure_500_nested_arrays.json deleted file mode 100644 index 7118405..0000000 --- a/test/JSONTestSuite/test_parsing/i_structure_500_nested_arrays.json +++ /dev/null @@ -1 +0,0 @@ -[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/i_structure_UTF-8_BOM_empty_object.json b/test/JSONTestSuite/test_parsing/i_structure_UTF-8_BOM_empty_object.json deleted file mode 100755 index 22fdca1..0000000 --- a/test/JSONTestSuite/test_parsing/i_structure_UTF-8_BOM_empty_object.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_1_true_without_comma.json b/test/JSONTestSuite/test_parsing/n_array_1_true_without_comma.json deleted file mode 100644 index c14e3f6..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_1_true_without_comma.json +++ /dev/null @@ -1 +0,0 @@ -[1 true] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_a_invalid_utf8.json b/test/JSONTestSuite/test_parsing/n_array_a_invalid_utf8.json deleted file mode 100644 index 38a86e2..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_a_invalid_utf8.json +++ /dev/null @@ -1 +0,0 @@ -[a] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_colon_instead_of_comma.json b/test/JSONTestSuite/test_parsing/n_array_colon_instead_of_comma.json deleted file mode 100644 index 0d02ad4..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_colon_instead_of_comma.json +++ /dev/null @@ -1 +0,0 @@ -["": 1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_comma_after_close.json b/test/JSONTestSuite/test_parsing/n_array_comma_after_close.json deleted file mode 100644 index 2ccba8d..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_comma_after_close.json +++ /dev/null @@ -1 +0,0 @@ -[""], \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_comma_and_number.json b/test/JSONTestSuite/test_parsing/n_array_comma_and_number.json deleted file mode 100755 index d2c84e3..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_comma_and_number.json +++ /dev/null @@ -1 +0,0 @@ -[,1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_double_comma.json b/test/JSONTestSuite/test_parsing/n_array_double_comma.json deleted file mode 100755 index 0431712..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_double_comma.json +++ /dev/null @@ -1 +0,0 @@ -[1,,2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_double_extra_comma.json b/test/JSONTestSuite/test_parsing/n_array_double_extra_comma.json deleted file mode 100644 index 3f01d31..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_double_extra_comma.json +++ /dev/null @@ -1 +0,0 @@ -["x",,] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_extra_close.json b/test/JSONTestSuite/test_parsing/n_array_extra_close.json deleted file mode 100644 index c12f9fa..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_extra_close.json +++ /dev/null @@ -1 +0,0 @@ -["x"]] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_extra_comma.json b/test/JSONTestSuite/test_parsing/n_array_extra_comma.json deleted file mode 100644 index 5f8ce18..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_extra_comma.json +++ /dev/null @@ -1 +0,0 @@ -["",] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_incomplete.json b/test/JSONTestSuite/test_parsing/n_array_incomplete.json deleted file mode 100644 index cc65b0b..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_incomplete.json +++ /dev/null @@ -1 +0,0 @@ -["x" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_incomplete_invalid_value.json b/test/JSONTestSuite/test_parsing/n_array_incomplete_invalid_value.json deleted file mode 100644 index c21a8f6..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_incomplete_invalid_value.json +++ /dev/null @@ -1 +0,0 @@ -[x \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_inner_array_no_comma.json b/test/JSONTestSuite/test_parsing/n_array_inner_array_no_comma.json deleted file mode 100644 index c70b716..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_inner_array_no_comma.json +++ /dev/null @@ -1 +0,0 @@ -[3[4]] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_invalid_utf8.json b/test/JSONTestSuite/test_parsing/n_array_invalid_utf8.json deleted file mode 100644 index 6099d34..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_invalid_utf8.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_items_separated_by_semicolon.json b/test/JSONTestSuite/test_parsing/n_array_items_separated_by_semicolon.json deleted file mode 100755 index d4bd731..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_items_separated_by_semicolon.json +++ /dev/null @@ -1 +0,0 @@ -[1:2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_just_comma.json b/test/JSONTestSuite/test_parsing/n_array_just_comma.json deleted file mode 100755 index 9d7077c..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_just_comma.json +++ /dev/null @@ -1 +0,0 @@ -[,] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_just_minus.json b/test/JSONTestSuite/test_parsing/n_array_just_minus.json deleted file mode 100755 index 29501c6..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_just_minus.json +++ /dev/null @@ -1 +0,0 @@ -[-] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_missing_value.json b/test/JSONTestSuite/test_parsing/n_array_missing_value.json deleted file mode 100644 index 3a6ba86..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_missing_value.json +++ /dev/null @@ -1 +0,0 @@ -[ , ""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_newlines_unclosed.json b/test/JSONTestSuite/test_parsing/n_array_newlines_unclosed.json deleted file mode 100644 index 6466800..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_newlines_unclosed.json +++ /dev/null @@ -1,3 +0,0 @@ -["a", -4 -,1, \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_number_and_comma.json b/test/JSONTestSuite/test_parsing/n_array_number_and_comma.json deleted file mode 100755 index 13f6f1d..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_number_and_comma.json +++ /dev/null @@ -1 +0,0 @@ -[1,] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_number_and_several_commas.json b/test/JSONTestSuite/test_parsing/n_array_number_and_several_commas.json deleted file mode 100755 index 0ac408c..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_number_and_several_commas.json +++ /dev/null @@ -1 +0,0 @@ -[1,,] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_spaces_vertical_tab_formfeed.json b/test/JSONTestSuite/test_parsing/n_array_spaces_vertical_tab_formfeed.json deleted file mode 100755 index 6cd7cf5..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_spaces_vertical_tab_formfeed.json +++ /dev/null @@ -1 +0,0 @@ -[" a"\f] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_star_inside.json b/test/JSONTestSuite/test_parsing/n_array_star_inside.json deleted file mode 100755 index 5a51946..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_star_inside.json +++ /dev/null @@ -1 +0,0 @@ -[*] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_unclosed.json b/test/JSONTestSuite/test_parsing/n_array_unclosed.json deleted file mode 100644 index 0607330..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_unclosed.json +++ /dev/null @@ -1 +0,0 @@ -["" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_unclosed_trailing_comma.json b/test/JSONTestSuite/test_parsing/n_array_unclosed_trailing_comma.json deleted file mode 100644 index 6604698..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_unclosed_trailing_comma.json +++ /dev/null @@ -1 +0,0 @@ -[1, \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_unclosed_with_new_lines.json b/test/JSONTestSuite/test_parsing/n_array_unclosed_with_new_lines.json deleted file mode 100644 index 4f61de3..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_unclosed_with_new_lines.json +++ /dev/null @@ -1,3 +0,0 @@ -[1, -1 -,1 \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_array_unclosed_with_object_inside.json b/test/JSONTestSuite/test_parsing/n_array_unclosed_with_object_inside.json deleted file mode 100644 index 043a87e..0000000 --- a/test/JSONTestSuite/test_parsing/n_array_unclosed_with_object_inside.json +++ /dev/null @@ -1 +0,0 @@ -[{} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_incomplete_false.json b/test/JSONTestSuite/test_parsing/n_incomplete_false.json deleted file mode 100644 index eb18c6a..0000000 --- a/test/JSONTestSuite/test_parsing/n_incomplete_false.json +++ /dev/null @@ -1 +0,0 @@ -[fals] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_incomplete_null.json b/test/JSONTestSuite/test_parsing/n_incomplete_null.json deleted file mode 100644 index c18ef53..0000000 --- a/test/JSONTestSuite/test_parsing/n_incomplete_null.json +++ /dev/null @@ -1 +0,0 @@ -[nul] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_incomplete_true.json b/test/JSONTestSuite/test_parsing/n_incomplete_true.json deleted file mode 100644 index f451ac6..0000000 --- a/test/JSONTestSuite/test_parsing/n_incomplete_true.json +++ /dev/null @@ -1 +0,0 @@ -[tru] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_multidigit_number_then_00.json b/test/JSONTestSuite/test_parsing/n_multidigit_number_then_00.json deleted file mode 100644 index c22507b864f7f089c91c1eb85b1b15cc63b943a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4 LcmXpsGG+h(0mJ~8 diff --git a/test/JSONTestSuite/test_parsing/n_number_++.json b/test/JSONTestSuite/test_parsing/n_number_++.json deleted file mode 100644 index bdb62aa..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_++.json +++ /dev/null @@ -1 +0,0 @@ -[++1234] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_+1.json b/test/JSONTestSuite/test_parsing/n_number_+1.json deleted file mode 100755 index 3cbe58c..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_+1.json +++ /dev/null @@ -1 +0,0 @@ -[+1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_+Inf.json b/test/JSONTestSuite/test_parsing/n_number_+Inf.json deleted file mode 100755 index 871ae14..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_+Inf.json +++ /dev/null @@ -1 +0,0 @@ -[+Inf] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_-01.json b/test/JSONTestSuite/test_parsing/n_number_-01.json deleted file mode 100755 index 0df32ba..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_-01.json +++ /dev/null @@ -1 +0,0 @@ -[-01] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_-1.0..json b/test/JSONTestSuite/test_parsing/n_number_-1.0..json deleted file mode 100755 index 7cf55a8..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_-1.0..json +++ /dev/null @@ -1 +0,0 @@ -[-1.0.] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_-2..json b/test/JSONTestSuite/test_parsing/n_number_-2..json deleted file mode 100755 index 9be8436..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_-2..json +++ /dev/null @@ -1 +0,0 @@ -[-2.] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_-NaN.json b/test/JSONTestSuite/test_parsing/n_number_-NaN.json deleted file mode 100755 index f61615d..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_-NaN.json +++ /dev/null @@ -1 +0,0 @@ -[-NaN] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_.-1.json b/test/JSONTestSuite/test_parsing/n_number_.-1.json deleted file mode 100644 index 1c9f2dd..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_.-1.json +++ /dev/null @@ -1 +0,0 @@ -[.-1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_.2e-3.json b/test/JSONTestSuite/test_parsing/n_number_.2e-3.json deleted file mode 100755 index c6c976f..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_.2e-3.json +++ /dev/null @@ -1 +0,0 @@ -[.2e-3] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_0.1.2.json b/test/JSONTestSuite/test_parsing/n_number_0.1.2.json deleted file mode 100755 index c83a256..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_0.1.2.json +++ /dev/null @@ -1 +0,0 @@ -[0.1.2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_0.3e+.json b/test/JSONTestSuite/test_parsing/n_number_0.3e+.json deleted file mode 100644 index a55a1bf..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_0.3e+.json +++ /dev/null @@ -1 +0,0 @@ -[0.3e+] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_0.3e.json b/test/JSONTestSuite/test_parsing/n_number_0.3e.json deleted file mode 100644 index 3dd5df4..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_0.3e.json +++ /dev/null @@ -1 +0,0 @@ -[0.3e] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_0.e1.json b/test/JSONTestSuite/test_parsing/n_number_0.e1.json deleted file mode 100644 index c92c71c..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_0.e1.json +++ /dev/null @@ -1 +0,0 @@ -[0.e1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_0_capital_E+.json b/test/JSONTestSuite/test_parsing/n_number_0_capital_E+.json deleted file mode 100644 index 3ba2c7d..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_0_capital_E+.json +++ /dev/null @@ -1 +0,0 @@ -[0E+] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_0_capital_E.json b/test/JSONTestSuite/test_parsing/n_number_0_capital_E.json deleted file mode 100755 index 5301840..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_0_capital_E.json +++ /dev/null @@ -1 +0,0 @@ -[0E] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_0e+.json b/test/JSONTestSuite/test_parsing/n_number_0e+.json deleted file mode 100644 index 8ab0bc4..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_0e+.json +++ /dev/null @@ -1 +0,0 @@ -[0e+] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_0e.json b/test/JSONTestSuite/test_parsing/n_number_0e.json deleted file mode 100644 index 47ec421..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_0e.json +++ /dev/null @@ -1 +0,0 @@ -[0e] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_1.0e+.json b/test/JSONTestSuite/test_parsing/n_number_1.0e+.json deleted file mode 100755 index cd84b9f..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_1.0e+.json +++ /dev/null @@ -1 +0,0 @@ -[1.0e+] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_1.0e-.json b/test/JSONTestSuite/test_parsing/n_number_1.0e-.json deleted file mode 100755 index 4eb7afa..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_1.0e-.json +++ /dev/null @@ -1 +0,0 @@ -[1.0e-] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_1.0e.json b/test/JSONTestSuite/test_parsing/n_number_1.0e.json deleted file mode 100755 index 21753f4..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_1.0e.json +++ /dev/null @@ -1 +0,0 @@ -[1.0e] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_1_000.json b/test/JSONTestSuite/test_parsing/n_number_1_000.json deleted file mode 100755 index 7b18b66..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_1_000.json +++ /dev/null @@ -1 +0,0 @@ -[1 000.0] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_1eE2.json b/test/JSONTestSuite/test_parsing/n_number_1eE2.json deleted file mode 100755 index 4318a34..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_1eE2.json +++ /dev/null @@ -1 +0,0 @@ -[1eE2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_2.e+3.json b/test/JSONTestSuite/test_parsing/n_number_2.e+3.json deleted file mode 100755 index 4442f39..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_2.e+3.json +++ /dev/null @@ -1 +0,0 @@ -[2.e+3] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_2.e-3.json b/test/JSONTestSuite/test_parsing/n_number_2.e-3.json deleted file mode 100755 index a65060e..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_2.e-3.json +++ /dev/null @@ -1 +0,0 @@ -[2.e-3] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_2.e3.json b/test/JSONTestSuite/test_parsing/n_number_2.e3.json deleted file mode 100755 index 66f7cf7..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_2.e3.json +++ /dev/null @@ -1 +0,0 @@ -[2.e3] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_9.e+.json b/test/JSONTestSuite/test_parsing/n_number_9.e+.json deleted file mode 100644 index 732a7b1..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_9.e+.json +++ /dev/null @@ -1 +0,0 @@ -[9.e+] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_Inf.json b/test/JSONTestSuite/test_parsing/n_number_Inf.json deleted file mode 100755 index c40c734..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_Inf.json +++ /dev/null @@ -1 +0,0 @@ -[Inf] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_NaN.json b/test/JSONTestSuite/test_parsing/n_number_NaN.json deleted file mode 100755 index 4992317..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_NaN.json +++ /dev/null @@ -1 +0,0 @@ -[NaN] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_U+FF11_fullwidth_digit_one.json b/test/JSONTestSuite/test_parsing/n_number_U+FF11_fullwidth_digit_one.json deleted file mode 100644 index b14587e..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_U+FF11_fullwidth_digit_one.json +++ /dev/null @@ -1 +0,0 @@ -[1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_expression.json b/test/JSONTestSuite/test_parsing/n_number_expression.json deleted file mode 100644 index 76fdbc8..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_expression.json +++ /dev/null @@ -1 +0,0 @@ -[1+2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_hex_1_digit.json b/test/JSONTestSuite/test_parsing/n_number_hex_1_digit.json deleted file mode 100644 index 3b21488..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_hex_1_digit.json +++ /dev/null @@ -1 +0,0 @@ -[0x1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_hex_2_digits.json b/test/JSONTestSuite/test_parsing/n_number_hex_2_digits.json deleted file mode 100644 index 83e516a..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_hex_2_digits.json +++ /dev/null @@ -1 +0,0 @@ -[0x42] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_infinity.json b/test/JSONTestSuite/test_parsing/n_number_infinity.json deleted file mode 100755 index 8c2baf7..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_infinity.json +++ /dev/null @@ -1 +0,0 @@ -[Infinity] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_invalid+-.json b/test/JSONTestSuite/test_parsing/n_number_invalid+-.json deleted file mode 100644 index 1cce602..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_invalid+-.json +++ /dev/null @@ -1 +0,0 @@ -[0e+-1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_invalid-negative-real.json b/test/JSONTestSuite/test_parsing/n_number_invalid-negative-real.json deleted file mode 100644 index 5fc3c1e..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_invalid-negative-real.json +++ /dev/null @@ -1 +0,0 @@ -[-123.123foo] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-bigger-int.json b/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-bigger-int.json deleted file mode 100644 index 3b97e58..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-bigger-int.json +++ /dev/null @@ -1 +0,0 @@ -[123] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-exponent.json b/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-exponent.json deleted file mode 100644 index ea35d72..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-exponent.json +++ /dev/null @@ -1 +0,0 @@ -[1e1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-int.json b/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-int.json deleted file mode 100644 index 371226e..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_invalid-utf-8-in-int.json +++ /dev/null @@ -1 +0,0 @@ -[0] diff --git a/test/JSONTestSuite/test_parsing/n_number_minus_infinity.json b/test/JSONTestSuite/test_parsing/n_number_minus_infinity.json deleted file mode 100755 index cf4133d..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_minus_infinity.json +++ /dev/null @@ -1 +0,0 @@ -[-Infinity] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_minus_sign_with_trailing_garbage.json b/test/JSONTestSuite/test_parsing/n_number_minus_sign_with_trailing_garbage.json deleted file mode 100644 index a6d8e78..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_minus_sign_with_trailing_garbage.json +++ /dev/null @@ -1 +0,0 @@ -[-foo] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_minus_space_1.json b/test/JSONTestSuite/test_parsing/n_number_minus_space_1.json deleted file mode 100644 index 9a5ebed..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_minus_space_1.json +++ /dev/null @@ -1 +0,0 @@ -[- 1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_neg_int_starting_with_zero.json b/test/JSONTestSuite/test_parsing/n_number_neg_int_starting_with_zero.json deleted file mode 100644 index 67af096..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_neg_int_starting_with_zero.json +++ /dev/null @@ -1 +0,0 @@ -[-012] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_neg_real_without_int_part.json b/test/JSONTestSuite/test_parsing/n_number_neg_real_without_int_part.json deleted file mode 100755 index 1f2a434..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_neg_real_without_int_part.json +++ /dev/null @@ -1 +0,0 @@ -[-.123] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_neg_with_garbage_at_end.json b/test/JSONTestSuite/test_parsing/n_number_neg_with_garbage_at_end.json deleted file mode 100644 index 2aa7311..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_neg_with_garbage_at_end.json +++ /dev/null @@ -1 +0,0 @@ -[-1x] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_real_garbage_after_e.json b/test/JSONTestSuite/test_parsing/n_number_real_garbage_after_e.json deleted file mode 100644 index 9213dfc..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_real_garbage_after_e.json +++ /dev/null @@ -1 +0,0 @@ -[1ea] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_real_with_invalid_utf8_after_e.json b/test/JSONTestSuite/test_parsing/n_number_real_with_invalid_utf8_after_e.json deleted file mode 100644 index 1e52ef9..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_real_with_invalid_utf8_after_e.json +++ /dev/null @@ -1 +0,0 @@ -[1e] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_real_without_fractional_part.json b/test/JSONTestSuite/test_parsing/n_number_real_without_fractional_part.json deleted file mode 100755 index 1de287c..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_real_without_fractional_part.json +++ /dev/null @@ -1 +0,0 @@ -[1.] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_starting_with_dot.json b/test/JSONTestSuite/test_parsing/n_number_starting_with_dot.json deleted file mode 100755 index f682dbd..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_starting_with_dot.json +++ /dev/null @@ -1 +0,0 @@ -[.123] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_with_alpha.json b/test/JSONTestSuite/test_parsing/n_number_with_alpha.json deleted file mode 100644 index 1e42d81..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_with_alpha.json +++ /dev/null @@ -1 +0,0 @@ -[1.2a-3] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_with_alpha_char.json b/test/JSONTestSuite/test_parsing/n_number_with_alpha_char.json deleted file mode 100644 index b79dacc..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_with_alpha_char.json +++ /dev/null @@ -1 +0,0 @@ -[1.8011670033376514H-308] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_number_with_leading_zero.json b/test/JSONTestSuite/test_parsing/n_number_with_leading_zero.json deleted file mode 100755 index 7106da1..0000000 --- a/test/JSONTestSuite/test_parsing/n_number_with_leading_zero.json +++ /dev/null @@ -1 +0,0 @@ -[012] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_bad_value.json b/test/JSONTestSuite/test_parsing/n_object_bad_value.json deleted file mode 100644 index a03a8c0..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_bad_value.json +++ /dev/null @@ -1 +0,0 @@ -["x", truth] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_bracket_key.json b/test/JSONTestSuite/test_parsing/n_object_bracket_key.json deleted file mode 100644 index cc443b4..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_bracket_key.json +++ /dev/null @@ -1 +0,0 @@ -{[: "x"} diff --git a/test/JSONTestSuite/test_parsing/n_object_comma_instead_of_colon.json b/test/JSONTestSuite/test_parsing/n_object_comma_instead_of_colon.json deleted file mode 100644 index 8d56377..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_comma_instead_of_colon.json +++ /dev/null @@ -1 +0,0 @@ -{"x", null} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_double_colon.json b/test/JSONTestSuite/test_parsing/n_object_double_colon.json deleted file mode 100644 index 80e8c7b..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_double_colon.json +++ /dev/null @@ -1 +0,0 @@ -{"x"::"b"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_emoji.json b/test/JSONTestSuite/test_parsing/n_object_emoji.json deleted file mode 100644 index cb4078e..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_emoji.json +++ /dev/null @@ -1 +0,0 @@ -{🇨🇭} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_garbage_at_end.json b/test/JSONTestSuite/test_parsing/n_object_garbage_at_end.json deleted file mode 100644 index 80c42cb..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_garbage_at_end.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"a" 123} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_key_with_single_quotes.json b/test/JSONTestSuite/test_parsing/n_object_key_with_single_quotes.json deleted file mode 100755 index 77c3275..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_key_with_single_quotes.json +++ /dev/null @@ -1 +0,0 @@ -{key: 'value'} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json b/test/JSONTestSuite/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json deleted file mode 100644 index aa2cb63..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_lone_continuation_byte_in_key_and_trailing_comma.json +++ /dev/null @@ -1 +0,0 @@ -{"":"0",} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_missing_colon.json b/test/JSONTestSuite/test_parsing/n_object_missing_colon.json deleted file mode 100644 index b98eff6..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_missing_colon.json +++ /dev/null @@ -1 +0,0 @@ -{"a" b} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_missing_key.json b/test/JSONTestSuite/test_parsing/n_object_missing_key.json deleted file mode 100755 index b4fb0f5..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_missing_key.json +++ /dev/null @@ -1 +0,0 @@ -{:"b"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_missing_semicolon.json b/test/JSONTestSuite/test_parsing/n_object_missing_semicolon.json deleted file mode 100755 index e345138..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_missing_semicolon.json +++ /dev/null @@ -1 +0,0 @@ -{"a" "b"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_missing_value.json b/test/JSONTestSuite/test_parsing/n_object_missing_value.json deleted file mode 100644 index 3ef538a..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_missing_value.json +++ /dev/null @@ -1 +0,0 @@ -{"a": \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_no-colon.json b/test/JSONTestSuite/test_parsing/n_object_no-colon.json deleted file mode 100644 index f3797b3..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_no-colon.json +++ /dev/null @@ -1 +0,0 @@ -{"a" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_non_string_key.json b/test/JSONTestSuite/test_parsing/n_object_non_string_key.json deleted file mode 100755 index b9945b3..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_non_string_key.json +++ /dev/null @@ -1 +0,0 @@ -{1:1} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_non_string_key_but_huge_number_instead.json b/test/JSONTestSuite/test_parsing/n_object_non_string_key_but_huge_number_instead.json deleted file mode 100755 index b37fa86..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_non_string_key_but_huge_number_instead.json +++ /dev/null @@ -1 +0,0 @@ -{9999E9999:1} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_repeated_null_null.json b/test/JSONTestSuite/test_parsing/n_object_repeated_null_null.json deleted file mode 100755 index f7d2959..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_repeated_null_null.json +++ /dev/null @@ -1 +0,0 @@ -{null:null,null:null} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_several_trailing_commas.json b/test/JSONTestSuite/test_parsing/n_object_several_trailing_commas.json deleted file mode 100755 index 3c9afe8..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_several_trailing_commas.json +++ /dev/null @@ -1 +0,0 @@ -{"id":0,,,,,} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_single_quote.json b/test/JSONTestSuite/test_parsing/n_object_single_quote.json deleted file mode 100644 index e5cdf97..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_single_quote.json +++ /dev/null @@ -1 +0,0 @@ -{'a':0} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_trailing_comma.json b/test/JSONTestSuite/test_parsing/n_object_trailing_comma.json deleted file mode 100755 index a4b0250..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_trailing_comma.json +++ /dev/null @@ -1 +0,0 @@ -{"id":0,} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_trailing_comment.json b/test/JSONTestSuite/test_parsing/n_object_trailing_comment.json deleted file mode 100644 index a372c65..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_trailing_comment.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b"}/**/ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_trailing_comment_open.json b/test/JSONTestSuite/test_parsing/n_object_trailing_comment_open.json deleted file mode 100644 index d557f41..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_trailing_comment_open.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b"}/**// \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open.json b/test/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open.json deleted file mode 100644 index e335136..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b"}// \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.json b/test/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.json deleted file mode 100644 index d892e49..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_trailing_comment_slash_open_incomplete.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b"}/ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_two_commas_in_a_row.json b/test/JSONTestSuite/test_parsing/n_object_two_commas_in_a_row.json deleted file mode 100755 index 7c639ae..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_two_commas_in_a_row.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b",,"c":"d"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_unquoted_key.json b/test/JSONTestSuite/test_parsing/n_object_unquoted_key.json deleted file mode 100644 index 8ba1372..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_unquoted_key.json +++ /dev/null @@ -1 +0,0 @@ -{a: "b"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_unterminated-value.json b/test/JSONTestSuite/test_parsing/n_object_unterminated-value.json deleted file mode 100644 index 7fe699a..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_unterminated-value.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"a \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_with_single_string.json b/test/JSONTestSuite/test_parsing/n_object_with_single_string.json deleted file mode 100644 index d63f7fb..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_with_single_string.json +++ /dev/null @@ -1 +0,0 @@ -{ "foo" : "bar", "a" } \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_object_with_trailing_garbage.json b/test/JSONTestSuite/test_parsing/n_object_with_trailing_garbage.json deleted file mode 100644 index 787c8f0..0000000 --- a/test/JSONTestSuite/test_parsing/n_object_with_trailing_garbage.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b"}# \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_single_space.json b/test/JSONTestSuite/test_parsing/n_single_space.json deleted file mode 100755 index 0519ecb..0000000 --- a/test/JSONTestSuite/test_parsing/n_single_space.json +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape.json b/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape.json deleted file mode 100644 index acec66d..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape.json +++ /dev/null @@ -1 +0,0 @@ -["\uD800\"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u.json b/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u.json deleted file mode 100644 index e834b05..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u.json +++ /dev/null @@ -1 +0,0 @@ -["\uD800\u"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1.json b/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1.json deleted file mode 100644 index a04cd34..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1.json +++ /dev/null @@ -1 +0,0 @@ -["\uD800\u1"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1x.json b/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1x.json deleted file mode 100644 index bfbd234..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_1_surrogate_then_escape_u1x.json +++ /dev/null @@ -1 +0,0 @@ -["\uD800\u1x"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_accentuated_char_no_quotes.json b/test/JSONTestSuite/test_parsing/n_string_accentuated_char_no_quotes.json deleted file mode 100644 index fd68956..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_accentuated_char_no_quotes.json +++ /dev/null @@ -1 +0,0 @@ -[é] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_backslash_00.json b/test/JSONTestSuite/test_parsing/n_string_backslash_00.json deleted file mode 100644 index b5bf267b5d4ee922d20cec1543b66d1530ff76cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6 Ncma!6ieXTS1pox&0a*Y5 diff --git a/test/JSONTestSuite/test_parsing/n_string_escape_x.json b/test/JSONTestSuite/test_parsing/n_string_escape_x.json deleted file mode 100644 index fae2919..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_escape_x.json +++ /dev/null @@ -1 +0,0 @@ -["\x00"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_escaped_backslash_bad.json b/test/JSONTestSuite/test_parsing/n_string_escaped_backslash_bad.json deleted file mode 100755 index 016fcb4..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_escaped_backslash_bad.json +++ /dev/null @@ -1 +0,0 @@ -["\\\"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_escaped_ctrl_char_tab.json b/test/JSONTestSuite/test_parsing/n_string_escaped_ctrl_char_tab.json deleted file mode 100644 index f35ea38..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_escaped_ctrl_char_tab.json +++ /dev/null @@ -1 +0,0 @@ -["\ "] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_escaped_emoji.json b/test/JSONTestSuite/test_parsing/n_string_escaped_emoji.json deleted file mode 100644 index a277754..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_escaped_emoji.json +++ /dev/null @@ -1 +0,0 @@ -["\🌀"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_incomplete_escape.json b/test/JSONTestSuite/test_parsing/n_string_incomplete_escape.json deleted file mode 100755 index 3415c33..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_incomplete_escape.json +++ /dev/null @@ -1 +0,0 @@ -["\"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_incomplete_escaped_character.json b/test/JSONTestSuite/test_parsing/n_string_incomplete_escaped_character.json deleted file mode 100755 index 0f2197e..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_incomplete_escaped_character.json +++ /dev/null @@ -1 +0,0 @@ -["\u00A"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_incomplete_surrogate.json b/test/JSONTestSuite/test_parsing/n_string_incomplete_surrogate.json deleted file mode 100755 index 75504a6..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_incomplete_surrogate.json +++ /dev/null @@ -1 +0,0 @@ -["\uD834\uDd"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_incomplete_surrogate_escape_invalid.json b/test/JSONTestSuite/test_parsing/n_string_incomplete_surrogate_escape_invalid.json deleted file mode 100755 index bd96560..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_incomplete_surrogate_escape_invalid.json +++ /dev/null @@ -1 +0,0 @@ -["\uD800\uD800\x"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_invalid-utf-8-in-escape.json b/test/JSONTestSuite/test_parsing/n_string_invalid-utf-8-in-escape.json deleted file mode 100644 index 0c43006..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_invalid-utf-8-in-escape.json +++ /dev/null @@ -1 +0,0 @@ -["\u"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_invalid_backslash_esc.json b/test/JSONTestSuite/test_parsing/n_string_invalid_backslash_esc.json deleted file mode 100755 index d1eb609..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_invalid_backslash_esc.json +++ /dev/null @@ -1 +0,0 @@ -["\a"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_invalid_unicode_escape.json b/test/JSONTestSuite/test_parsing/n_string_invalid_unicode_escape.json deleted file mode 100644 index 7608cb6..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_invalid_unicode_escape.json +++ /dev/null @@ -1 +0,0 @@ -["\uqqqq"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_invalid_utf8_after_escape.json b/test/JSONTestSuite/test_parsing/n_string_invalid_utf8_after_escape.json deleted file mode 100644 index 2f757a2..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_invalid_utf8_after_escape.json +++ /dev/null @@ -1 +0,0 @@ -["\"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_leading_uescaped_thinspace.json b/test/JSONTestSuite/test_parsing/n_string_leading_uescaped_thinspace.json deleted file mode 100755 index 7b297c6..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_leading_uescaped_thinspace.json +++ /dev/null @@ -1 +0,0 @@ -[\u0020"asd"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_no_quotes_with_bad_escape.json b/test/JSONTestSuite/test_parsing/n_string_no_quotes_with_bad_escape.json deleted file mode 100644 index 01bc70a..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_no_quotes_with_bad_escape.json +++ /dev/null @@ -1 +0,0 @@ -[\n] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_single_doublequote.json b/test/JSONTestSuite/test_parsing/n_string_single_doublequote.json deleted file mode 100755 index 9d68933..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_single_doublequote.json +++ /dev/null @@ -1 +0,0 @@ -" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_single_quote.json b/test/JSONTestSuite/test_parsing/n_string_single_quote.json deleted file mode 100644 index caff239..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_single_quote.json +++ /dev/null @@ -1 +0,0 @@ -['single quote'] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_single_string_no_double_quotes.json b/test/JSONTestSuite/test_parsing/n_string_single_string_no_double_quotes.json deleted file mode 100755 index f2ba8f8..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_single_string_no_double_quotes.json +++ /dev/null @@ -1 +0,0 @@ -abc \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_start_escape_unclosed.json b/test/JSONTestSuite/test_parsing/n_string_start_escape_unclosed.json deleted file mode 100644 index db62a46..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_start_escape_unclosed.json +++ /dev/null @@ -1 +0,0 @@ -["\ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_unescaped_ctrl_char.json b/test/JSONTestSuite/test_parsing/n_string_unescaped_ctrl_char.json deleted file mode 100755 index 9f21348071d3d736bdd469f159cea674c09237af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7 Ocma!6N@Pe>iUj}$`2oKG diff --git a/test/JSONTestSuite/test_parsing/n_string_unescaped_newline.json b/test/JSONTestSuite/test_parsing/n_string_unescaped_newline.json deleted file mode 100644 index 700d360..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_unescaped_newline.json +++ /dev/null @@ -1,2 +0,0 @@ -["new -line"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_unescaped_tab.json b/test/JSONTestSuite/test_parsing/n_string_unescaped_tab.json deleted file mode 100644 index 160264a..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_unescaped_tab.json +++ /dev/null @@ -1 +0,0 @@ -[" "] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_unicode_CapitalU.json b/test/JSONTestSuite/test_parsing/n_string_unicode_CapitalU.json deleted file mode 100644 index 17332bb..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_unicode_CapitalU.json +++ /dev/null @@ -1 +0,0 @@ -"\UA66D" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_string_with_trailing_garbage.json b/test/JSONTestSuite/test_parsing/n_string_with_trailing_garbage.json deleted file mode 100644 index efe3bd2..0000000 --- a/test/JSONTestSuite/test_parsing/n_string_with_trailing_garbage.json +++ /dev/null @@ -1 +0,0 @@ -""x \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_100000_opening_arrays.json b/test/JSONTestSuite/test_parsing/n_structure_100000_opening_arrays.json deleted file mode 100644 index a4823ee..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_100000_opening_arrays.json +++ /dev/null @@ -1 +0,0 @@ -[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_U+2060_word_joined.json b/test/JSONTestSuite/test_parsing/n_structure_U+2060_word_joined.json deleted file mode 100644 index 81156a6..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_U+2060_word_joined.json +++ /dev/null @@ -1 +0,0 @@ -[⁠] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_UTF8_BOM_no_data.json b/test/JSONTestSuite/test_parsing/n_structure_UTF8_BOM_no_data.json deleted file mode 100755 index 5f28270..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_UTF8_BOM_no_data.json +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_angle_bracket_..json b/test/JSONTestSuite/test_parsing/n_structure_angle_bracket_..json deleted file mode 100755 index a56fef0..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_angle_bracket_..json +++ /dev/null @@ -1 +0,0 @@ -<.> \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_angle_bracket_null.json b/test/JSONTestSuite/test_parsing/n_structure_angle_bracket_null.json deleted file mode 100755 index 617f262..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_angle_bracket_null.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_array_trailing_garbage.json b/test/JSONTestSuite/test_parsing/n_structure_array_trailing_garbage.json deleted file mode 100644 index 5a745e6..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_array_trailing_garbage.json +++ /dev/null @@ -1 +0,0 @@ -[1]x \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_array_with_extra_array_close.json b/test/JSONTestSuite/test_parsing/n_structure_array_with_extra_array_close.json deleted file mode 100755 index 6cfb139..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_array_with_extra_array_close.json +++ /dev/null @@ -1 +0,0 @@ -[1]] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_array_with_unclosed_string.json b/test/JSONTestSuite/test_parsing/n_structure_array_with_unclosed_string.json deleted file mode 100755 index ba6b178..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_array_with_unclosed_string.json +++ /dev/null @@ -1 +0,0 @@ -["asd] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_ascii-unicode-identifier.json b/test/JSONTestSuite/test_parsing/n_structure_ascii-unicode-identifier.json deleted file mode 100644 index ef2ab62..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_ascii-unicode-identifier.json +++ /dev/null @@ -1 +0,0 @@ -aå \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_capitalized_True.json b/test/JSONTestSuite/test_parsing/n_structure_capitalized_True.json deleted file mode 100755 index 7cd8846..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_capitalized_True.json +++ /dev/null @@ -1 +0,0 @@ -[True] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_close_unopened_array.json b/test/JSONTestSuite/test_parsing/n_structure_close_unopened_array.json deleted file mode 100755 index d2af0c6..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_close_unopened_array.json +++ /dev/null @@ -1 +0,0 @@ -1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_comma_instead_of_closing_brace.json b/test/JSONTestSuite/test_parsing/n_structure_comma_instead_of_closing_brace.json deleted file mode 100644 index ac61b82..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_comma_instead_of_closing_brace.json +++ /dev/null @@ -1 +0,0 @@ -{"x": true, \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_double_array.json b/test/JSONTestSuite/test_parsing/n_structure_double_array.json deleted file mode 100755 index 058d162..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_double_array.json +++ /dev/null @@ -1 +0,0 @@ -[][] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_end_array.json b/test/JSONTestSuite/test_parsing/n_structure_end_array.json deleted file mode 100644 index 54caf60..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_end_array.json +++ /dev/null @@ -1 +0,0 @@ -] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_incomplete_UTF8_BOM.json b/test/JSONTestSuite/test_parsing/n_structure_incomplete_UTF8_BOM.json deleted file mode 100755 index bfcdd51..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_incomplete_UTF8_BOM.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_lone-invalid-utf-8.json b/test/JSONTestSuite/test_parsing/n_structure_lone-invalid-utf-8.json deleted file mode 100644 index 8b1296c..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_lone-invalid-utf-8.json +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_lone-open-bracket.json b/test/JSONTestSuite/test_parsing/n_structure_lone-open-bracket.json deleted file mode 100644 index 8e2f0be..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_lone-open-bracket.json +++ /dev/null @@ -1 +0,0 @@ -[ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_no_data.json b/test/JSONTestSuite/test_parsing/n_structure_no_data.json deleted file mode 100644 index e69de29..0000000 diff --git a/test/JSONTestSuite/test_parsing/n_structure_null-byte-outside-string.json b/test/JSONTestSuite/test_parsing/n_structure_null-byte-outside-string.json deleted file mode 100644 index 326db14422a756e9bd39221edf37b844cb8471c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3 Kcma!Mhy?%vaR9jh diff --git a/test/JSONTestSuite/test_parsing/n_structure_number_with_trailing_garbage.json b/test/JSONTestSuite/test_parsing/n_structure_number_with_trailing_garbage.json deleted file mode 100644 index 0746539..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_number_with_trailing_garbage.json +++ /dev/null @@ -1 +0,0 @@ -2@ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_object_followed_by_closing_object.json b/test/JSONTestSuite/test_parsing/n_structure_object_followed_by_closing_object.json deleted file mode 100644 index aa9ebae..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_object_followed_by_closing_object.json +++ /dev/null @@ -1 +0,0 @@ -{}} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_object_unclosed_no_value.json b/test/JSONTestSuite/test_parsing/n_structure_object_unclosed_no_value.json deleted file mode 100644 index 17d0451..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_object_unclosed_no_value.json +++ /dev/null @@ -1 +0,0 @@ -{"": \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_object_with_comment.json b/test/JSONTestSuite/test_parsing/n_structure_object_with_comment.json deleted file mode 100644 index ed1b569..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_object_with_comment.json +++ /dev/null @@ -1 +0,0 @@ -{"a":/*comment*/"b"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_object_with_trailing_garbage.json b/test/JSONTestSuite/test_parsing/n_structure_object_with_trailing_garbage.json deleted file mode 100644 index 9ca2336..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_object_with_trailing_garbage.json +++ /dev/null @@ -1 +0,0 @@ -{"a": true} "x" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_array_apostrophe.json b/test/JSONTestSuite/test_parsing/n_structure_open_array_apostrophe.json deleted file mode 100644 index 8bebe3a..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_array_apostrophe.json +++ /dev/null @@ -1 +0,0 @@ -[' \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_array_comma.json b/test/JSONTestSuite/test_parsing/n_structure_open_array_comma.json deleted file mode 100644 index 6295fdc..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_array_comma.json +++ /dev/null @@ -1 +0,0 @@ -[, \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_array_object.json b/test/JSONTestSuite/test_parsing/n_structure_open_array_object.json deleted file mode 100644 index e870445..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_array_object.json +++ /dev/null @@ -1 +0,0 @@ -[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"":[{"": diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_array_open_object.json b/test/JSONTestSuite/test_parsing/n_structure_open_array_open_object.json deleted file mode 100644 index 7a63c8c..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_array_open_object.json +++ /dev/null @@ -1 +0,0 @@ -[{ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_array_open_string.json b/test/JSONTestSuite/test_parsing/n_structure_open_array_open_string.json deleted file mode 100644 index 9822a6b..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_array_open_string.json +++ /dev/null @@ -1 +0,0 @@ -["a \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_array_string.json b/test/JSONTestSuite/test_parsing/n_structure_open_array_string.json deleted file mode 100644 index 42a6193..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_array_string.json +++ /dev/null @@ -1 +0,0 @@ -["a" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_object.json b/test/JSONTestSuite/test_parsing/n_structure_open_object.json deleted file mode 100644 index 81750b9..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_object.json +++ /dev/null @@ -1 +0,0 @@ -{ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_object_close_array.json b/test/JSONTestSuite/test_parsing/n_structure_open_object_close_array.json deleted file mode 100755 index eebc700..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_object_close_array.json +++ /dev/null @@ -1 +0,0 @@ -{] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_object_comma.json b/test/JSONTestSuite/test_parsing/n_structure_open_object_comma.json deleted file mode 100644 index 47bc910..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_object_comma.json +++ /dev/null @@ -1 +0,0 @@ -{, \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_object_open_array.json b/test/JSONTestSuite/test_parsing/n_structure_open_object_open_array.json deleted file mode 100644 index 381ede5..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_object_open_array.json +++ /dev/null @@ -1 +0,0 @@ -{[ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_object_open_string.json b/test/JSONTestSuite/test_parsing/n_structure_open_object_open_string.json deleted file mode 100644 index 328c30c..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_object_open_string.json +++ /dev/null @@ -1 +0,0 @@ -{"a \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_object_string_with_apostrophes.json b/test/JSONTestSuite/test_parsing/n_structure_open_object_string_with_apostrophes.json deleted file mode 100644 index 9dba170..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_object_string_with_apostrophes.json +++ /dev/null @@ -1 +0,0 @@ -{'a' \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_open_open.json b/test/JSONTestSuite/test_parsing/n_structure_open_open.json deleted file mode 100644 index 841fd5f..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_open_open.json +++ /dev/null @@ -1 +0,0 @@ -["\{["\{["\{["\{ \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_single_eacute.json b/test/JSONTestSuite/test_parsing/n_structure_single_eacute.json deleted file mode 100644 index 92a39f3..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_single_eacute.json +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_single_star.json b/test/JSONTestSuite/test_parsing/n_structure_single_star.json deleted file mode 100755 index f59ec20..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_single_star.json +++ /dev/null @@ -1 +0,0 @@ -* \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_trailing_#.json b/test/JSONTestSuite/test_parsing/n_structure_trailing_#.json deleted file mode 100644 index 8986110..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_trailing_#.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b"}#{} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_uescaped_LF_before_string.json b/test/JSONTestSuite/test_parsing/n_structure_uescaped_LF_before_string.json deleted file mode 100755 index df2f0f2..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_uescaped_LF_before_string.json +++ /dev/null @@ -1 +0,0 @@ -[\u000A""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_unclosed_array.json b/test/JSONTestSuite/test_parsing/n_structure_unclosed_array.json deleted file mode 100755 index 1120951..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_unclosed_array.json +++ /dev/null @@ -1 +0,0 @@ -[1 \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_partial_null.json b/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_partial_null.json deleted file mode 100644 index 0d59176..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_partial_null.json +++ /dev/null @@ -1 +0,0 @@ -[ false, nul \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_false.json b/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_false.json deleted file mode 100644 index a2ff850..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_false.json +++ /dev/null @@ -1 +0,0 @@ -[ true, fals \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_true.json b/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_true.json deleted file mode 100644 index 3149e8f..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_unclosed_array_unfinished_true.json +++ /dev/null @@ -1 +0,0 @@ -[ false, tru \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_unclosed_object.json b/test/JSONTestSuite/test_parsing/n_structure_unclosed_object.json deleted file mode 100755 index 694d69d..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_unclosed_object.json +++ /dev/null @@ -1 +0,0 @@ -{"asd":"asd" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_unicode-identifier.json b/test/JSONTestSuite/test_parsing/n_structure_unicode-identifier.json deleted file mode 100644 index 7284aea..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_unicode-identifier.json +++ /dev/null @@ -1 +0,0 @@ -å \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json b/test/JSONTestSuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json deleted file mode 100755 index 81156a6..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_whitespace_U+2060_word_joiner.json +++ /dev/null @@ -1 +0,0 @@ -[⁠] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/n_structure_whitespace_formfeed.json b/test/JSONTestSuite/test_parsing/n_structure_whitespace_formfeed.json deleted file mode 100755 index a9ea535..0000000 --- a/test/JSONTestSuite/test_parsing/n_structure_whitespace_formfeed.json +++ /dev/null @@ -1 +0,0 @@ -[ ] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_arraysWithSpaces.json b/test/JSONTestSuite/test_parsing/y_array_arraysWithSpaces.json deleted file mode 100755 index 5822907..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_arraysWithSpaces.json +++ /dev/null @@ -1 +0,0 @@ -[[] ] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_empty-string.json b/test/JSONTestSuite/test_parsing/y_array_empty-string.json deleted file mode 100644 index 93b6be2..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_empty-string.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_empty.json b/test/JSONTestSuite/test_parsing/y_array_empty.json deleted file mode 100755 index 0637a08..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_empty.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_ending_with_newline.json b/test/JSONTestSuite/test_parsing/y_array_ending_with_newline.json deleted file mode 100755 index eac5f7b..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_ending_with_newline.json +++ /dev/null @@ -1 +0,0 @@ -["a"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_false.json b/test/JSONTestSuite/test_parsing/y_array_false.json deleted file mode 100644 index 67b2f07..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_false.json +++ /dev/null @@ -1 +0,0 @@ -[false] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_heterogeneous.json b/test/JSONTestSuite/test_parsing/y_array_heterogeneous.json deleted file mode 100755 index d3c1e26..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_heterogeneous.json +++ /dev/null @@ -1 +0,0 @@ -[null, 1, "1", {}] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_null.json b/test/JSONTestSuite/test_parsing/y_array_null.json deleted file mode 100644 index 500db4a..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_null.json +++ /dev/null @@ -1 +0,0 @@ -[null] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_with_1_and_newline.json b/test/JSONTestSuite/test_parsing/y_array_with_1_and_newline.json deleted file mode 100644 index 9948255..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_with_1_and_newline.json +++ /dev/null @@ -1,2 +0,0 @@ -[1 -] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_with_leading_space.json b/test/JSONTestSuite/test_parsing/y_array_with_leading_space.json deleted file mode 100755 index 18bfe64..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_with_leading_space.json +++ /dev/null @@ -1 +0,0 @@ - [1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_with_several_null.json b/test/JSONTestSuite/test_parsing/y_array_with_several_null.json deleted file mode 100755 index 99f6c5d..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_with_several_null.json +++ /dev/null @@ -1 +0,0 @@ -[1,null,null,null,2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_array_with_trailing_space.json b/test/JSONTestSuite/test_parsing/y_array_with_trailing_space.json deleted file mode 100755 index de9e7a9..0000000 --- a/test/JSONTestSuite/test_parsing/y_array_with_trailing_space.json +++ /dev/null @@ -1 +0,0 @@ -[2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number.json b/test/JSONTestSuite/test_parsing/y_number.json deleted file mode 100644 index e5f5cc3..0000000 --- a/test/JSONTestSuite/test_parsing/y_number.json +++ /dev/null @@ -1 +0,0 @@ -[123e65] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_0e+1.json b/test/JSONTestSuite/test_parsing/y_number_0e+1.json deleted file mode 100755 index d1d3967..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_0e+1.json +++ /dev/null @@ -1 +0,0 @@ -[0e+1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_0e1.json b/test/JSONTestSuite/test_parsing/y_number_0e1.json deleted file mode 100755 index 3283a79..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_0e1.json +++ /dev/null @@ -1 +0,0 @@ -[0e1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_after_space.json b/test/JSONTestSuite/test_parsing/y_number_after_space.json deleted file mode 100644 index 623570d..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_after_space.json +++ /dev/null @@ -1 +0,0 @@ -[ 4] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_double_close_to_zero.json b/test/JSONTestSuite/test_parsing/y_number_double_close_to_zero.json deleted file mode 100755 index 96555ff..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_double_close_to_zero.json +++ /dev/null @@ -1 +0,0 @@ -[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001] diff --git a/test/JSONTestSuite/test_parsing/y_number_int_with_exp.json b/test/JSONTestSuite/test_parsing/y_number_int_with_exp.json deleted file mode 100755 index a4ca9e7..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_int_with_exp.json +++ /dev/null @@ -1 +0,0 @@ -[20e1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_minus_zero.json b/test/JSONTestSuite/test_parsing/y_number_minus_zero.json deleted file mode 100755 index 37af131..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_minus_zero.json +++ /dev/null @@ -1 +0,0 @@ -[-0] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_negative_int.json b/test/JSONTestSuite/test_parsing/y_number_negative_int.json deleted file mode 100644 index 8e30f8b..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_negative_int.json +++ /dev/null @@ -1 +0,0 @@ -[-123] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_negative_one.json b/test/JSONTestSuite/test_parsing/y_number_negative_one.json deleted file mode 100644 index 99d21a2..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_negative_one.json +++ /dev/null @@ -1 +0,0 @@ -[-1] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_negative_zero.json b/test/JSONTestSuite/test_parsing/y_number_negative_zero.json deleted file mode 100644 index 37af131..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_negative_zero.json +++ /dev/null @@ -1 +0,0 @@ -[-0] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_real_capital_e.json b/test/JSONTestSuite/test_parsing/y_number_real_capital_e.json deleted file mode 100644 index 6edbdfc..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_real_capital_e.json +++ /dev/null @@ -1 +0,0 @@ -[1E22] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_real_capital_e_neg_exp.json b/test/JSONTestSuite/test_parsing/y_number_real_capital_e_neg_exp.json deleted file mode 100644 index 0a01bd3..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_real_capital_e_neg_exp.json +++ /dev/null @@ -1 +0,0 @@ -[1E-2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_real_capital_e_pos_exp.json b/test/JSONTestSuite/test_parsing/y_number_real_capital_e_pos_exp.json deleted file mode 100644 index 5a8fc09..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_real_capital_e_pos_exp.json +++ /dev/null @@ -1 +0,0 @@ -[1E+2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_real_exponent.json b/test/JSONTestSuite/test_parsing/y_number_real_exponent.json deleted file mode 100644 index da2522d..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_real_exponent.json +++ /dev/null @@ -1 +0,0 @@ -[123e45] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_real_fraction_exponent.json b/test/JSONTestSuite/test_parsing/y_number_real_fraction_exponent.json deleted file mode 100644 index 3944a7a..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_real_fraction_exponent.json +++ /dev/null @@ -1 +0,0 @@ -[123.456e78] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_real_neg_exp.json b/test/JSONTestSuite/test_parsing/y_number_real_neg_exp.json deleted file mode 100644 index ca40d3c..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_real_neg_exp.json +++ /dev/null @@ -1 +0,0 @@ -[1e-2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_real_pos_exponent.json b/test/JSONTestSuite/test_parsing/y_number_real_pos_exponent.json deleted file mode 100644 index 343601d..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_real_pos_exponent.json +++ /dev/null @@ -1 +0,0 @@ -[1e+2] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_simple_int.json b/test/JSONTestSuite/test_parsing/y_number_simple_int.json deleted file mode 100644 index e47f69a..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_simple_int.json +++ /dev/null @@ -1 +0,0 @@ -[123] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_number_simple_real.json b/test/JSONTestSuite/test_parsing/y_number_simple_real.json deleted file mode 100644 index b02878e..0000000 --- a/test/JSONTestSuite/test_parsing/y_number_simple_real.json +++ /dev/null @@ -1 +0,0 @@ -[123.456789] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object.json b/test/JSONTestSuite/test_parsing/y_object.json deleted file mode 100755 index 78262ed..0000000 --- a/test/JSONTestSuite/test_parsing/y_object.json +++ /dev/null @@ -1 +0,0 @@ -{"asd":"sdf", "dfg":"fgh"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_basic.json b/test/JSONTestSuite/test_parsing/y_object_basic.json deleted file mode 100755 index 646bbe7..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_basic.json +++ /dev/null @@ -1 +0,0 @@ -{"asd":"sdf"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_duplicated_key.json b/test/JSONTestSuite/test_parsing/y_object_duplicated_key.json deleted file mode 100755 index bbc2e1c..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_duplicated_key.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b","a":"c"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_duplicated_key_and_value.json b/test/JSONTestSuite/test_parsing/y_object_duplicated_key_and_value.json deleted file mode 100755 index 211581c..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_duplicated_key_and_value.json +++ /dev/null @@ -1 +0,0 @@ -{"a":"b","a":"b"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_empty.json b/test/JSONTestSuite/test_parsing/y_object_empty.json deleted file mode 100644 index 9e26dfe..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_empty.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_empty_key.json b/test/JSONTestSuite/test_parsing/y_object_empty_key.json deleted file mode 100755 index c0013d3..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_empty_key.json +++ /dev/null @@ -1 +0,0 @@ -{"":0} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_escaped_null_in_key.json b/test/JSONTestSuite/test_parsing/y_object_escaped_null_in_key.json deleted file mode 100644 index 593f0f6..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_escaped_null_in_key.json +++ /dev/null @@ -1 +0,0 @@ -{"foo\u0000bar": 42} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_extreme_numbers.json b/test/JSONTestSuite/test_parsing/y_object_extreme_numbers.json deleted file mode 100644 index a0d3531..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_extreme_numbers.json +++ /dev/null @@ -1 +0,0 @@ -{ "min": -1.0e+28, "max": 1.0e+28 } \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_long_strings.json b/test/JSONTestSuite/test_parsing/y_object_long_strings.json deleted file mode 100644 index bdc4a08..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_long_strings.json +++ /dev/null @@ -1 +0,0 @@ -{"x":[{"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}], "id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_simple.json b/test/JSONTestSuite/test_parsing/y_object_simple.json deleted file mode 100644 index dacac91..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_simple.json +++ /dev/null @@ -1 +0,0 @@ -{"a":[]} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_string_unicode.json b/test/JSONTestSuite/test_parsing/y_object_string_unicode.json deleted file mode 100644 index 8effdb2..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_string_unicode.json +++ /dev/null @@ -1 +0,0 @@ -{"title":"\u041f\u043e\u043b\u0442\u043e\u0440\u0430 \u0417\u0435\u043c\u043b\u0435\u043a\u043e\u043f\u0430" } \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_object_with_newlines.json b/test/JSONTestSuite/test_parsing/y_object_with_newlines.json deleted file mode 100644 index 246ec6b..0000000 --- a/test/JSONTestSuite/test_parsing/y_object_with_newlines.json +++ /dev/null @@ -1,3 +0,0 @@ -{ -"a": "b" -} \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json b/test/JSONTestSuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json deleted file mode 100755 index 9967dde..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_1_2_3_bytes_UTF-8_sequences.json +++ /dev/null @@ -1 +0,0 @@ -["\u0060\u012a\u12AB"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pair.json b/test/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pair.json deleted file mode 100755 index 996875c..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pair.json +++ /dev/null @@ -1 +0,0 @@ -["\uD801\udc37"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pairs.json b/test/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pairs.json deleted file mode 100755 index 3401021..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_accepted_surrogate_pairs.json +++ /dev/null @@ -1 +0,0 @@ -["\ud83d\ude39\ud83d\udc8d"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_allowed_escapes.json b/test/JSONTestSuite/test_parsing/y_string_allowed_escapes.json deleted file mode 100644 index 7f49553..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_allowed_escapes.json +++ /dev/null @@ -1 +0,0 @@ -["\"\\\/\b\f\n\r\t"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_backslash_and_u_escaped_zero.json b/test/JSONTestSuite/test_parsing/y_string_backslash_and_u_escaped_zero.json deleted file mode 100755 index d4439ed..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_backslash_and_u_escaped_zero.json +++ /dev/null @@ -1 +0,0 @@ -["\\u0000"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_backslash_doublequotes.json b/test/JSONTestSuite/test_parsing/y_string_backslash_doublequotes.json deleted file mode 100644 index ae03243..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_backslash_doublequotes.json +++ /dev/null @@ -1 +0,0 @@ -["\""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_comments.json b/test/JSONTestSuite/test_parsing/y_string_comments.json deleted file mode 100644 index 2260c20..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_comments.json +++ /dev/null @@ -1 +0,0 @@ -["a/*b*/c/*d//e"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_double_escape_a.json b/test/JSONTestSuite/test_parsing/y_string_double_escape_a.json deleted file mode 100644 index 6715d6f..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_double_escape_a.json +++ /dev/null @@ -1 +0,0 @@ -["\\a"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_double_escape_n.json b/test/JSONTestSuite/test_parsing/y_string_double_escape_n.json deleted file mode 100644 index 44ca56c..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_double_escape_n.json +++ /dev/null @@ -1 +0,0 @@ -["\\n"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_escaped_control_character.json b/test/JSONTestSuite/test_parsing/y_string_escaped_control_character.json deleted file mode 100644 index 5b014a9..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_escaped_control_character.json +++ /dev/null @@ -1 +0,0 @@ -["\u0012"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_escaped_noncharacter.json b/test/JSONTestSuite/test_parsing/y_string_escaped_noncharacter.json deleted file mode 100755 index 2ff52e2..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_escaped_noncharacter.json +++ /dev/null @@ -1 +0,0 @@ -["\uFFFF"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_in_array.json b/test/JSONTestSuite/test_parsing/y_string_in_array.json deleted file mode 100755 index 21d7ae4..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_in_array.json +++ /dev/null @@ -1 +0,0 @@ -["asd"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_in_array_with_leading_space.json b/test/JSONTestSuite/test_parsing/y_string_in_array_with_leading_space.json deleted file mode 100755 index 9e1887c..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_in_array_with_leading_space.json +++ /dev/null @@ -1 +0,0 @@ -[ "asd"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_last_surrogates_1_and_2.json b/test/JSONTestSuite/test_parsing/y_string_last_surrogates_1_and_2.json deleted file mode 100644 index 3919cef..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_last_surrogates_1_and_2.json +++ /dev/null @@ -1 +0,0 @@ -["\uDBFF\uDFFF"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_nbsp_uescaped.json b/test/JSONTestSuite/test_parsing/y_string_nbsp_uescaped.json deleted file mode 100644 index 2085ab1..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_nbsp_uescaped.json +++ /dev/null @@ -1 +0,0 @@ -["new\u00A0line"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json b/test/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json deleted file mode 100755 index 059e4d9..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+10FFFF.json +++ /dev/null @@ -1 +0,0 @@ -["􏿿"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json b/test/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json deleted file mode 100755 index 4c913bd..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_nonCharacterInUTF-8_U+FFFF.json +++ /dev/null @@ -1 +0,0 @@ -["￿"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_null_escape.json b/test/JSONTestSuite/test_parsing/y_string_null_escape.json deleted file mode 100644 index c1ad844..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_null_escape.json +++ /dev/null @@ -1 +0,0 @@ -["\u0000"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_one-byte-utf-8.json b/test/JSONTestSuite/test_parsing/y_string_one-byte-utf-8.json deleted file mode 100644 index 1571859..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_one-byte-utf-8.json +++ /dev/null @@ -1 +0,0 @@ -["\u002c"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_pi.json b/test/JSONTestSuite/test_parsing/y_string_pi.json deleted file mode 100644 index 9df11ae..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_pi.json +++ /dev/null @@ -1 +0,0 @@ -["π"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json b/test/JSONTestSuite/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json deleted file mode 100755 index 10a33a1..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_reservedCharacterInUTF-8_U+1BFFF.json +++ /dev/null @@ -1 +0,0 @@ -["𛿿"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_simple_ascii.json b/test/JSONTestSuite/test_parsing/y_string_simple_ascii.json deleted file mode 100644 index 8cadf7d..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_simple_ascii.json +++ /dev/null @@ -1 +0,0 @@ -["asd "] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_space.json b/test/JSONTestSuite/test_parsing/y_string_space.json deleted file mode 100644 index efd782c..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_space.json +++ /dev/null @@ -1 +0,0 @@ -" " \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json b/test/JSONTestSuite/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json deleted file mode 100755 index 7620b66..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json +++ /dev/null @@ -1 +0,0 @@ -["\uD834\uDd1e"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_three-byte-utf-8.json b/test/JSONTestSuite/test_parsing/y_string_three-byte-utf-8.json deleted file mode 100644 index 108f1d6..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_three-byte-utf-8.json +++ /dev/null @@ -1 +0,0 @@ -["\u0821"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_two-byte-utf-8.json b/test/JSONTestSuite/test_parsing/y_string_two-byte-utf-8.json deleted file mode 100644 index 461503c..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_two-byte-utf-8.json +++ /dev/null @@ -1 +0,0 @@ -["\u0123"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_u+2028_line_sep.json b/test/JSONTestSuite/test_parsing/y_string_u+2028_line_sep.json deleted file mode 100755 index 897b602..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_u+2028_line_sep.json +++ /dev/null @@ -1 +0,0 @@ -["
"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_u+2029_par_sep.json b/test/JSONTestSuite/test_parsing/y_string_u+2029_par_sep.json deleted file mode 100755 index 8cd998c..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_u+2029_par_sep.json +++ /dev/null @@ -1 +0,0 @@ -["
"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_uEscape.json b/test/JSONTestSuite/test_parsing/y_string_uEscape.json deleted file mode 100755 index f7b41a0..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_uEscape.json +++ /dev/null @@ -1 +0,0 @@ -["\u0061\u30af\u30EA\u30b9"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_uescaped_newline.json b/test/JSONTestSuite/test_parsing/y_string_uescaped_newline.json deleted file mode 100644 index 3a5a220..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_uescaped_newline.json +++ /dev/null @@ -1 +0,0 @@ -["new\u000Aline"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unescaped_char_delete.json b/test/JSONTestSuite/test_parsing/y_string_unescaped_char_delete.json deleted file mode 100755 index 7d064f4..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unescaped_char_delete.json +++ /dev/null @@ -1 +0,0 @@ -[""] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode.json b/test/JSONTestSuite/test_parsing/y_string_unicode.json deleted file mode 100644 index 3598095..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode.json +++ /dev/null @@ -1 +0,0 @@ -["\uA66D"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicodeEscapedBackslash.json b/test/JSONTestSuite/test_parsing/y_string_unicodeEscapedBackslash.json deleted file mode 100755 index 0bb3b51..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicodeEscapedBackslash.json +++ /dev/null @@ -1 +0,0 @@ -["\u005C"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode_2.json b/test/JSONTestSuite/test_parsing/y_string_unicode_2.json deleted file mode 100644 index a7dcb97..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode_2.json +++ /dev/null @@ -1 +0,0 @@ -["⍂㈴⍂"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode_U+10FFFE_nonchar.json b/test/JSONTestSuite/test_parsing/y_string_unicode_U+10FFFE_nonchar.json deleted file mode 100644 index 9a8370b..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode_U+10FFFE_nonchar.json +++ /dev/null @@ -1 +0,0 @@ -["\uDBFF\uDFFE"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode_U+1FFFE_nonchar.json b/test/JSONTestSuite/test_parsing/y_string_unicode_U+1FFFE_nonchar.json deleted file mode 100644 index c51f8ae..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode_U+1FFFE_nonchar.json +++ /dev/null @@ -1 +0,0 @@ -["\uD83F\uDFFE"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json b/test/JSONTestSuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json deleted file mode 100644 index 626d5f8..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json +++ /dev/null @@ -1 +0,0 @@ -["\u200B"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json b/test/JSONTestSuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json deleted file mode 100644 index 1e23972..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode_U+2064_invisible_plus.json +++ /dev/null @@ -1 +0,0 @@ -["\u2064"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode_U+FDD0_nonchar.json b/test/JSONTestSuite/test_parsing/y_string_unicode_U+FDD0_nonchar.json deleted file mode 100644 index 18ef151..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode_U+FDD0_nonchar.json +++ /dev/null @@ -1 +0,0 @@ -["\uFDD0"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode_U+FFFE_nonchar.json b/test/JSONTestSuite/test_parsing/y_string_unicode_U+FFFE_nonchar.json deleted file mode 100644 index 13d261f..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode_U+FFFE_nonchar.json +++ /dev/null @@ -1 +0,0 @@ -["\uFFFE"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_unicode_escaped_double_quote.json b/test/JSONTestSuite/test_parsing/y_string_unicode_escaped_double_quote.json deleted file mode 100755 index 4e62578..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_unicode_escaped_double_quote.json +++ /dev/null @@ -1 +0,0 @@ -["\u0022"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_utf8.json b/test/JSONTestSuite/test_parsing/y_string_utf8.json deleted file mode 100644 index 4087843..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_utf8.json +++ /dev/null @@ -1 +0,0 @@ -["€𝄞"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_string_with_del_character.json b/test/JSONTestSuite/test_parsing/y_string_with_del_character.json deleted file mode 100755 index 8bd2490..0000000 --- a/test/JSONTestSuite/test_parsing/y_string_with_del_character.json +++ /dev/null @@ -1 +0,0 @@ -["aa"] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_lonely_false.json b/test/JSONTestSuite/test_parsing/y_structure_lonely_false.json deleted file mode 100644 index 02e4a84..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_lonely_false.json +++ /dev/null @@ -1 +0,0 @@ -false \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_lonely_int.json b/test/JSONTestSuite/test_parsing/y_structure_lonely_int.json deleted file mode 100755 index f70d7bb..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_lonely_int.json +++ /dev/null @@ -1 +0,0 @@ -42 \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_lonely_negative_real.json b/test/JSONTestSuite/test_parsing/y_structure_lonely_negative_real.json deleted file mode 100755 index b5135a2..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_lonely_negative_real.json +++ /dev/null @@ -1 +0,0 @@ --0.1 \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_lonely_null.json b/test/JSONTestSuite/test_parsing/y_structure_lonely_null.json deleted file mode 100644 index ec747fa..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_lonely_null.json +++ /dev/null @@ -1 +0,0 @@ -null \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_lonely_string.json b/test/JSONTestSuite/test_parsing/y_structure_lonely_string.json deleted file mode 100755 index b6e982c..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_lonely_string.json +++ /dev/null @@ -1 +0,0 @@ -"asd" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_lonely_true.json b/test/JSONTestSuite/test_parsing/y_structure_lonely_true.json deleted file mode 100755 index f32a580..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_lonely_true.json +++ /dev/null @@ -1 +0,0 @@ -true \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_string_empty.json b/test/JSONTestSuite/test_parsing/y_structure_string_empty.json deleted file mode 100644 index 3cc762b..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_string_empty.json +++ /dev/null @@ -1 +0,0 @@ -"" \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_trailing_newline.json b/test/JSONTestSuite/test_parsing/y_structure_trailing_newline.json deleted file mode 100644 index 0c3426d..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_trailing_newline.json +++ /dev/null @@ -1 +0,0 @@ -["a"] diff --git a/test/JSONTestSuite/test_parsing/y_structure_true_in_array.json b/test/JSONTestSuite/test_parsing/y_structure_true_in_array.json deleted file mode 100644 index de601e3..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_true_in_array.json +++ /dev/null @@ -1 +0,0 @@ -[true] \ No newline at end of file diff --git a/test/JSONTestSuite/test_parsing/y_structure_whitespace_array.json b/test/JSONTestSuite/test_parsing/y_structure_whitespace_array.json deleted file mode 100644 index 2bedf7f..0000000 --- a/test/JSONTestSuite/test_parsing/y_structure_whitespace_array.json +++ /dev/null @@ -1 +0,0 @@ - [] \ No newline at end of file diff --git a/test/c.test.ts b/test/c.test.ts new file mode 100644 index 0000000..b607698 --- /dev/null +++ b/test/c.test.ts @@ -0,0 +1,86 @@ +/* Copyright (c) 2026 Richard Rodger and contributors, MIT License */ + +import { test, describe } from 'node:test' +import assert from 'node:assert' + +import { Jsonic } from 'jsonic' +import { C } from '../dist/c.js' + +const j = Jsonic.make().use(C, {}) + +describe('c parser smoke', () => { + + test('lex: tokenises a simple typedef declaration', () => { + // We don't yet drive a parse end-to-end with rich grammar, so this + // test exercises the lex pipeline only by asking for tokens. + const src = 'typedef int T;' + // Use jsonic.parse for the real entrypoint when grammar is ready; + // for now we just check it doesn't throw and produces *something*. + const out = j(src) + assert.ok(out, 'parse should produce a translation unit') + assert.equal(out.kind, 'translation_unit') + }) + + test('lex: tokenises arithmetic and identifiers', () => { + // Sanity: int x = 1 + 2; — currently only a primary initializer is + // accepted, so we use a single literal initializer. + const src = 'int x = 42;' + const out = j(src) + assert.equal(out.kind, 'translation_unit') + }) + + test('typedef registration: T becomes a typedef-name', () => { + // After `typedef int T;`, the next `T` should be classified by the + // identifier matcher as TYPEDEF_NAME thanks to symbol-table feedback. + const src = 'typedef int T;\nT x;\n' + const out = j(src) + assert.equal(out.kind, 'translation_unit') + assert.ok(out.children.length >= 2, 'expected two external declarations') + const second = out.children[1] + // The second external_declaration's children are token-refs in source + // order. Find the token whose src is 'T' and confirm it was emitted + // as a TYPEDEF_NAME, not an ID. + const tTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'T') + assert.ok(tTok, 'expected to find a token with src "T"') + assert.equal(tTok.tname, 'TYPEDEF_NAME', + 'after typedef registration, T must lex as TYPEDEF_NAME') + // And confirm `x` is still an ordinary ID (it was never typedef'd). + const xTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'x') + assert.ok(xTok, 'expected to find a token with src "x"') + assert.equal(xTok.tname, 'ID', 'x must lex as a plain ID') + }) + + test('keyword vs identifier boundary: int_value is one ID, not int + _value', () => { + const src = 'int int_value;' + const out = j(src) + const decl = out.children[0] + const tokens = decl.children.filter((c: any) => c.kind === 'token') + const srcs = tokens.map((t: any) => t.src) + assert.deepEqual(srcs, ['int', 'int_value', ';']) + assert.equal(tokens[0].tname, 'KW_INT') + assert.equal(tokens[1].tname, 'ID') + }) + + test('lex preserves block and line comments as trivia tokens', () => { + const src = '/* hi */ int x; // trail\n' + const out = j(src) + // A line comment after the ; is consumed by the next iteration's + // chomp; a block comment before the decl is its first child token. + assert.equal(out.kind, 'translation_unit') + const blockTokenAnywhere = out.children + .flatMap((d: any) => d.children) + .find((c: any) => c.kind === 'token' && c.tname === 'TRIVIA_BLOCK_COMMENT') + assert.ok(blockTokenAnywhere, 'block comment must survive in the AST') + }) + + test('punctuator dispatch: 3-char and 2-char operators', () => { + const src = 'a >>= 1;' + const out = j(src) + const tokens = out.children[0].children.filter((c: any) => c.kind === 'token') + assert.deepEqual( + tokens.map((t: any) => t.tname), + ['ID', 'PUNC_RSHIFT_ASSIGN', 'LIT_INT', 'PUNC_SEMI'], + ) + }) + +}) diff --git a/test/jsonc.test.ts b/test/jsonc.test.ts deleted file mode 100644 index b99ce58..0000000 --- a/test/jsonc.test.ts +++ /dev/null @@ -1,265 +0,0 @@ -/* Copyright (c) 2021-2025 Richard Rodger and other contributors, MIT License */ - -// Parse-level test cases in this file were ported from -// microsoft/node-jsonc-parser (src/test/json.test.ts), Copyright (c) -// Microsoft Corporation, MIT License. See THIRD_PARTY_NOTICES.md. - -import { test, describe } from 'node:test' -import assert from 'node:assert' - -import { Jsonic } from 'jsonic' -import { Jsonc } from '../dist/jsonc.js' - - -const j = Jsonic.make().use(Jsonc) - - -describe('jsonc', () => { - - test('happy', () => { - assert.deepEqual(j('{"a":1}'), { a: 1 }) - }) - - - test('comments', () => { - assert.deepEqual(j('// this is a comment'), undefined) - assert.deepEqual(j('// this is a comment\n'), undefined) - assert.deepEqual(j('/* this is a comment*/'), undefined) - assert.deepEqual(j('/* this is a \r\ncomment*/'), undefined) - assert.deepEqual(j('/* this is a \ncomment*/'), undefined) - assert.throws(() => j('/* this is a'), /unterminated_comment/) - assert.throws(() => j('/* this is a \ncomment'), /unterminated_comment/) - assert.throws(() => j('/ ttt'), /unexpected/) - }) - - - test('strings', () => { - assert.deepEqual(j('"test"'), 'test') - assert.deepEqual(j('"\\""'), '"') - assert.deepEqual(j('"\\/"'), '/') - assert.deepEqual(j('"\\b"'), '\b') - assert.deepEqual(j('"\\f"'), '\f') - assert.deepEqual(j('"\\n"'), '\n') - assert.deepEqual(j('"\\r"'), '\r') - assert.deepEqual(j('"\\t"'), '\t') - assert.deepEqual(j('"\u88ff"'), '\u88ff') - assert.deepEqual(j('"\u200B\u2028"'), '\u200B\u2028') - assert.throws(() => j('"\\v"'), /unexpected/) - assert.throws(() => j('"test'), /unterminated_string/) - assert.throws(() => j('"test\n"'), /unprintable/) - assert.throws(() => j('"\t"'), /unprintable/) - assert.throws(() => j('"\t "'), /unprintable/) - assert.throws(() => j('"\0 "'), /unprintable/) - }) - - - test('numbers', () => { - assert.deepEqual(j('0'), 0) - assert.deepEqual(j('0.1'), 0.1) - assert.deepEqual(j('-0.1'), -0.1) - assert.deepEqual(j('-1'), -1) - assert.deepEqual(j('1'), 1) - assert.deepEqual(j('123456789'), 123456789) - assert.deepEqual(j('10'), 10) - assert.deepEqual(j('90'), 90) - assert.deepEqual(j('90E+123'), 90E+123) - assert.deepEqual(j('90e+123'), 90e+123) - assert.deepEqual(j('90e-123'), 90e-123) - assert.deepEqual(j('90E-123'), 90E-123) - assert.deepEqual(j('90E123'), 90E123) - assert.deepEqual(j('90e123'), 90e123) - assert.deepEqual(j('01'), 1) - assert.deepEqual(j('-01'), -1) - assert.throws(() => j('-'), /unexpected/) - assert.throws(() => j('.0'), /unexpected/) - }) - - - test('keywords', () => { - assert.deepEqual(j('true'), true) - assert.deepEqual(j('false'), false) - assert.deepEqual(j('null'), null) - - assert.throws(() => j('nulllll'), /unexpected/) - assert.throws(() => j('True'), /unexpected/) - assert.throws(() => j('foo-bar'), /unexpected/) - assert.throws(() => j('foo bar'), /unexpected/) - - assert.deepEqual(j('false//hello'), false) - }) - - - test('trivia', () => { - assert.deepEqual(j(' '), undefined) - assert.deepEqual(j(' \t '), undefined) - assert.deepEqual(j(' \t \n \t '), undefined) - assert.deepEqual(j('\r\n'), undefined) - assert.deepEqual(j('\r'), undefined) - assert.deepEqual(j('\n'), undefined) - assert.deepEqual(j('\n\r'), undefined) - assert.deepEqual(j('\n \n'), undefined) - }) - - - test('literals', () => { - assert.deepEqual(j('true'), true) - assert.deepEqual(j('false'), false) - assert.deepEqual(j('null'), null) - assert.deepEqual(j('"foo"'), 'foo') - assert.deepEqual(j('"\\"-\\\\-\\/-\\b-\\f-\\n-\\r-\\t"'), '"-\\-/-\b-\f-\n-\r-\t') - assert.deepEqual(j('"\\u00DC"'), '\u00DC') - assert.deepEqual(j('9'), 9) - assert.deepEqual(j('-9'), -9) - assert.deepEqual(j('0.129'), 0.129) - assert.deepEqual(j('23e3'), 23e3) - assert.deepEqual(j('1.2E+3'), 1.2E+3) - assert.deepEqual(j('1.2E-3'), 1.2E-3) - assert.deepEqual(j('1.2E-3 // comment'), 1.2E-3) - }) - - - test('objects', () => { - assert.deepEqual(j('{}'), {}) - assert.deepEqual(j('{ "foo": true }'), { foo: true }) - assert.deepEqual(j('{ "bar": 8, "xoo": "foo" }'), { bar: 8, xoo: 'foo' }) - assert.deepEqual(j('{ "hello": [], "world": {} }'), { hello: [], world: {} }) - assert.deepEqual(j('{ "a": false, "b": true, "c": [ 7.4 ] }'), { a: false, b: true, c: [7.4] }) - assert.deepEqual(j('{ "lineComment": "//", "blockComment": ["/*", "*/"], "brackets": [ ["{", "}"], ["[", "]"], ["(", ")"] ] }'), - { lineComment: '//', blockComment: ['/*', '*/'], brackets: [['{', '}'], ['[', ']'], ['(', ')']] }) - assert.deepEqual(j('{ "hello": [], "world": {} }'), { hello: [], world: {} }) - assert.deepEqual(j('{ "hello": { "again": { "inside": 5 }, "world": 1 }}'), { hello: { again: { inside: 5 }, world: 1 } }) - assert.deepEqual(j('{ "foo": /*hello*/true }'), { foo: true }) - assert.deepEqual(j('{ "": true }'), { '': true }) - }) - - - test('arrays', () => { - assert.deepEqual(j('[]'), []) - assert.deepEqual(j('[ [], [ [] ]]'), [[], [[]]]) - assert.deepEqual(j('[ 1, 2, 3 ]'), [1, 2, 3]) - assert.deepEqual(j('[ { "a": null } ]'), [{ a: null }]) - }) - - - test('objects with errors', () => { - assert.throws(() => j('{,}')) - assert.throws(() => j('{ "foo": true, }')) - assert.throws(() => j('{ "bar": 8 "xoo": "foo" }')) - assert.throws(() => j('{ ,"bar": 8 }')) - assert.throws(() => j('{ ,"bar": 8, "foo" }')) - assert.throws(() => j('{ "bar": 8, "foo": }')) - assert.throws(() => j('{ 8, "foo": 9 }')) - }) - - - test('array with errors', () => { - assert.throws(() => j('[,]')) - assert.throws(() => j('[ 1 2, 3 ]')) - assert.throws(() => j('[ ,1, 2, 3 ]')) - assert.throws(() => j('[ ,1, 2, 3, ]')) - }) - - - test('errors', () => { - assert.throws(() => j('1,1')) - assert.throws(() => j('')) - }) - - - test('disallow comments', () => { - const nc = Jsonic.make().use(Jsonc, { disallowComments: true }) - - assert.deepEqual(nc('[ 1, 2, null, "foo" ]'), [1, 2, null, 'foo']) - assert.deepEqual(nc('{ "hello": [], "world": {} }'), { hello: [], world: {} }) - - assert.throws(() => nc('{ "foo": /*comment*/ true }')) - }) - - - test('trailing comma', () => { - const jc = Jsonic.make().use(Jsonc, { allowTrailingComma: true }) - - assert.deepEqual(jc('{ "hello": [], }'), { hello: [] }) - assert.deepEqual(jc('{ "hello": [] }'), { hello: [] }) - assert.deepEqual(jc('{ "hello": [], "world": {}, }'), { hello: [], world: {} }) - assert.deepEqual(jc('{ "hello": [], "world": {} }'), { hello: [], world: {} }) - assert.deepEqual(jc('[ 1, 2, ]'), [1, 2]) - assert.deepEqual(jc('[ 1, 2 ]'), [1, 2]) - - assert.throws(() => j('{ "hello": [], }')) - assert.throws(() => j('{ "hello": [], "world": {}, }')) - assert.throws(() => j('[ 1, 2, ]')) - }) - - test('misc', () => { - - assert.deepEqual(j('{ "foo": "bar" }'), { "foo": "bar" }) - assert.deepEqual(j('{ "foo": {"bar": 1, "car": 2 } }'), { "foo": { "bar": 1, "car": 2 } }) - assert.deepEqual(j('{ "foo": {"bar": 1, "car": 8 }, "goo": {} }'), { "foo": { "bar": 1, "car": 8 }, "goo": {} }) - assert.throws(() => j('{ "dep": {"bar": 1, "car": ')) - assert.throws(() => j('{ "dep": {"bar": 1,, "car": ')) - assert.throws(() => j('{ "dep": {"bar": "na", "dar": "ma", "car": } }')) - - assert.deepEqual(j('["foo", null ]'), ["foo", null]) - assert.throws(() => j('["foo", null, ]')) - assert.throws(() => j('["foo", null,, ]')) - assert.throws(() => j('[["foo", null,, ],')) - - assert.deepEqual(j('true'), true) - assert.deepEqual(j('false'), false) - assert.deepEqual(j('null'), null) - assert.deepEqual(j('23'), 23) - assert.deepEqual(j('-1.93e-19'), -1.93e-19) - assert.deepEqual(j('"hello"'), "hello") - - assert.deepEqual(j('[]'), []) - assert.deepEqual(j('[ 1 ]'), [1]) - assert.deepEqual(j('[ 1, "x"]'), [1, "x"]) - assert.deepEqual(j('[[]]'), [[]]) - assert.deepEqual(j('{ }'), {}) - assert.deepEqual(j('{ "val": 1 }'), { "val": 1 }) - assert.deepEqual(j('{"id": "$", "v": [ null, null] }'), - { "id": "$", "v": [null, null] }) - - assert.throws(() => j('{ "id": { "foo": { } } , }')) - - assert.deepEqual(j('{ }'), {}) - assert.deepEqual(j('{ "foo": "bar" }'), { "foo": "bar" }) - assert.deepEqual(j('{ "foo": { "goo": 3 } }'), { "foo": { "goo": 3 } }) - assert.deepEqual(j('[]'), []) - assert.deepEqual(j('[ true, null, [] ]'), [true, null, []]) - assert.deepEqual(j('[\r\n0,\r\n1,\r\n2\r\n]'), [0, 1, 2]) - assert.deepEqual(j('/* g */ { "foo": //f\n"bar" }'), { foo: 'bar' }) - assert.deepEqual(j('/* g\r\n */ { "foo": //f\n"bar" }'), { foo: 'bar' }) - assert.deepEqual(j('/* g\n */ { "foo": //f\n"bar"\n}'), { foo: 'bar' }) - assert.throws(() => j('{"prop1":"foo","prop2":"foo2","prop3":{"prp1":{""}}}' )) - assert.deepEqual(j('{ "key1": { "key11": [ "val111", "val112" ] }, "key2": [ { "key21": false, "key22": 221 }, null, [{}] ] }'), - { "key1": { "key11": ["val111", "val112"] }, "key2": [{ "key21": false, "key22": 221 }, null, [{}]] }) - - }) - - - // Verify the grammar() setting {rule:{alt:{g:'jsonc'}}} tagged every - // alt installed by the jsonc plugin with 'jsonc'. - test('alt g jsonc tag', () => { - const jc: any = Jsonic.make().use(Jsonc, { allowTrailingComma: true }) - const rsm: any = jc.internal().parser.rsm - - const checks: { rule: string; side: 'open' | 'close' }[] = [ - { rule: 'val', side: 'open' }, - { rule: 'pair', side: 'close' }, - { rule: 'elem', side: 'close' }, - ] - - for (const { rule, side } of checks) { - const rs = rsm[rule] - assert.ok(rs, `rule ${rule} missing`) - const alts = rs.def[side] as any[] - const tagged = alts.filter((a) => { - const g = Array.isArray(a.g) ? a.g : String(a.g || '').split(/\s*,\s*/) - return g.includes('jsonc') - }) - assert.ok(tagged.length > 0, `rule ${rule}.${side} has no 'jsonc'-tagged alt`) - } - }) -}) diff --git a/test/jsontestsuite.test.ts b/test/jsontestsuite.test.ts deleted file mode 100644 index 6dd4a25..0000000 --- a/test/jsontestsuite.test.ts +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2021-2025 Richard Rodger and other contributors, MIT License */ - -// Uses the nst/JSONTestSuite corpus (Copyright (c) 2016 Nicolas Seriot, -// MIT License) vendored at test/JSONTestSuite/. The upstream LICENSE is -// kept in place; see also THIRD_PARTY_NOTICES.md. - -// Runs the nst/JSONTestSuite (RFC 8259) against the jsonc plugin in strict -// mode (disallowComments: true, no trailing commas). Each file in -// test_parsing/ is classified by prefix: -// y_* must parse successfully -// n_* must be rejected (known-lenient cases pinned in N_KNOWN_LENIENT) -// i_* implementation-defined (recorded only) -// -// Known-lenient n_* entries reflect intentional jsonic relaxations vs. strict -// RFC 8259 (e.g. leading zeros, unquoted keys). They are pinned so the set -// is caught if it grows or shrinks. - -import { test, describe } from 'node:test' -import assert from 'node:assert' -import { readdirSync, readFileSync, existsSync } from 'node:fs' -import { join } from 'node:path' - -import { Jsonic } from 'jsonic' -import { Jsonc } from '../dist/jsonc.js' - -const SUITE_DIR = join(__dirname, '..', 'test', 'JSONTestSuite', 'test_parsing') - -const j = Jsonic.make().use(Jsonc, { disallowComments: true }) - -const parse = (src: string) => j(src) - -const files = existsSync(SUITE_DIR) - ? readdirSync(SUITE_DIR).filter((f) => f.endsWith('.json')).sort() - : [] - -// Cases jsonic intentionally accepts that RFC 8259 requires rejecting. -const N_KNOWN_LENIENT = new Set([ - 'n_array_comma_after_close.json', - 'n_number_+1.json', - 'n_number_-01.json', - 'n_number_-2..json', - 'n_number_0.e1.json', - 'n_number_2.e+3.json', - 'n_number_2.e-3.json', - 'n_number_2.e3.json', - 'n_number_neg_int_starting_with_zero.json', - 'n_number_neg_real_without_int_part.json', - 'n_number_real_without_fractional_part.json', - 'n_number_with_leading_zero.json', - 'n_object_non_string_key.json', - 'n_object_non_string_key_but_huge_number_instead.json', - 'n_object_repeated_null_null.json', - 'n_object_single_quote.json', - 'n_single_space.json', - 'n_string_escape_x.json', - 'n_string_single_quote.json', - 'n_structure_object_with_trailing_garbage.json', -]) - -describe('JSONTestSuite (RFC 8259)', () => { - if (0 === files.length) { - test('suite unavailable', () => { - console.warn(`JSONTestSuite not found at ${SUITE_DIR} — skipping.`) - }) - return - } - - test('y_* accept', () => { - const fails: { file: string; err: string }[] = [] - for (const f of files.filter((x) => x.startsWith('y_'))) { - const src = readFileSync(join(SUITE_DIR, f), 'utf8') - try { - parse(src) - } catch (e: any) { - fails.push({ file: f, err: e?.code || e?.message || String(e) }) - } - } - assert.deepEqual(fails, [], `y_* files that failed to parse:\n${fails.map((x) => ` ${x.file}: ${x.err}`).join('\n')}`) - }) - - test('n_* reject', () => { - const unexpectedAccept: string[] = [] - const unexpectedReject: string[] = [] - for (const f of files.filter((x) => x.startsWith('n_'))) { - const src = readFileSync(join(SUITE_DIR, f), 'utf8') - let accepted = false - try { - parse(src) - accepted = true - } catch { - // expected - } - const isLenient = N_KNOWN_LENIENT.has(f) - if (accepted && !isLenient) unexpectedAccept.push(f) - if (!accepted && isLenient) unexpectedReject.push(f) - } - assert.deepEqual( - { unexpectedAccept, unexpectedReject }, - { unexpectedAccept: [], unexpectedReject: [] }, - 'n_* divergence from pinned allowlist', - ) - }) - - test('i_* implementation-defined', () => { - const results: { file: string; accepted: boolean }[] = [] - for (const f of files.filter((x) => x.startsWith('i_'))) { - const src = readFileSync(join(SUITE_DIR, f), 'utf8') - try { - parse(src) - results.push({ file: f, accepted: true }) - } catch { - results.push({ file: f, accepted: false }) - } - } - assert.ok(results.length > 0, 'expected at least one i_* file') - }) -}) From e3048e6db3f78956896d2af08f94e3f8e4efdceb Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 13:45:23 +0000 Subject: [PATCH 02/25] Slice 2: multi-name typedef detection and smarter chomp termination MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace the single-name typedef heuristic with a real declarator walker. For each declarator in `typedef T1 *p, q[3], (*fn)(int);` the trailing identifier is found by stripping pointers, qualifiers, attribute groups, array/function postfixes, and recursing into parenthesised subdeclarators. Every declared name is registered. - splitDeclarators splits the init-declarator-list at top-level commas, ignoring commas inside (), [], or {}. - declaratorPart drops the initializer suffix at top-level `=` so initializer expressions don't pollute the name search. - findSpecBoundary identifies where declaration-specifiers end: it walks past storage-classes, type-specifiers, qualifiers, function- specifiers, attribute groups, and a single TYPEDEF_NAME, plus the optional brace-balanced body of struct/union/enum specifiers. - The chomper no longer auto-terminates at a top-level `}`. Instead it marks "just closed a brace" and only terminates if the next non- trivia token unambiguously begins a new external declaration (storage-class/type-specifier/qualifier keyword, attribute spec, TYPEDEF_NAME, preprocessor hash, or EOF). This lets `typedef struct { … } S;` and `enum E { … } var;` finish at the trailing `;`, while function definitions still terminate at `}` before the next top-level decl. Tests cover multi-name typedef, pointer/array/function-pointer typedefs, struct-tag typedefs, struct-with-body typedefs, mixed declarator lists, function-definition-then-decl, and brace-bearing initializers. --- src/c.ts | 329 +++++++++++++++++++++++++++++++++++++++++++++---- test/c.test.ts | 93 ++++++++++++++ 2 files changed, 401 insertions(+), 21 deletions(-) diff --git a/src/c.ts b/src/c.ts index 4481810..699ccf5 100644 --- a/src/c.ts +++ b/src/c.ts @@ -203,10 +203,17 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { const tkn = rule.o0 as Token rule.k.tokens.push(tkn) rule.node.children.push(tokenRef(tkn)) + rule.k.justClosedBrace = false if (tkn.name === 'PUNC_LBRACE') rule.k.depth++ else if (tkn.name === 'PUNC_RBRACE') { rule.k.depth-- - if (rule.k.depth <= 0) rule.k.terminated = true + if (rule.k.depth <= 0) { + // Don't auto-terminate. A closing top-level brace ends a + // function body, but for a struct/union/enum definition or + // compound literal it's followed by tokens (`S;`, `var,…;`, + // `;` alone). The close-alts decide based on lookahead. + rule.k.justClosedBrace = true + } } else if (tkn.name === 'PUNC_SEMI' && rule.k.depth === 0) { rule.k.terminated = true @@ -225,7 +232,19 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { }, g: 'extdecl-finish-eof', }, - // Hit terminator — wrap up and pop back to extdecl_loop. + // We just consumed a top-level `}` and the next non-trivia token + // looks like the start of a brand-new external declaration — + // terminate this one (function-definition body case). + { + c: (rule: Rule, ctx: Context) => + rule.k.justClosedBrace === true && + startsNewExternalDeclaration(ctx), + a: (rule: Rule, ctx: Context) => { + registerTypedefIfApplicable(rule.k.tokens as Token[], ctx) + }, + g: 'extdecl-finish-block', + }, + // Hit `;` at depth 0 — terminate. { c: (rule: Rule) => rule.k.terminated === true, a: (rule: Rule, ctx: Context) => { @@ -260,31 +279,299 @@ function anyTokenSet(jsonic: Jsonic): number[] { return _anyTokenSetCache } +// Names of tokens that count as trivia (whitespace, comments, line cont). +const TRIVIA_TOKEN_NAMES = new Set([ + '#SP', '#LN', '#CM', + 'TRIVIA_LINE_COMMENT', 'TRIVIA_BLOCK_COMMENT', 'TRIVIA_LINE_CONT', +]) + +// Type qualifiers in declarator pointer position. Used to skip past +// `* const`, `* volatile`, etc. when locating a declared name. +const PTR_QUALIFIER_TOKEN_NAMES = new Set([ + 'KW_CONST', 'KW_VOLATILE', 'KW_RESTRICT', 'KW__ATOMIC', + 'KW___CONST__', 'KW___CONST', + 'KW___VOLATILE__', 'KW___VOLATILE', + 'KW___RESTRICT__', 'KW___RESTRICT', +]) + +// Tokens that begin a type-specifier in declaration_specifiers. We use +// this to find the boundary between specifiers and declarators, by +// stopping at a non-specifier token (i.e. *, ID, ( as start-of-decl, +// etc). +const TYPE_SPEC_KEYWORD_NAMES = new Set([ + 'KW_VOID', 'KW_CHAR', 'KW_SHORT', 'KW_INT', 'KW_LONG', 'KW_FLOAT', + 'KW_DOUBLE', 'KW_SIGNED', 'KW_UNSIGNED', 'KW_BOOL', 'KW__BOOL', + 'KW__COMPLEX', 'KW__IMAGINARY', + 'KW___SIGNED__', 'KW___SIGNED', + 'KW___INT8', 'KW___INT16', 'KW___INT32', 'KW___INT64', + 'KW_STRUCT', 'KW_UNION', 'KW_ENUM', + 'KW_TYPEOF', 'KW_TYPEOF_UNQUAL', + 'KW___TYPEOF__', 'KW___TYPEOF', + 'KW__BITINT', +]) +const STORAGE_CLASS_NAMES = new Set([ + 'KW_TYPEDEF', 'KW_EXTERN', 'KW_STATIC', 'KW_AUTO', 'KW_REGISTER', + 'KW__THREAD_LOCAL', 'KW_THREAD_LOCAL', 'KW_CONSTEXPR', + 'KW___THREAD', +]) +const TYPE_QUALIFIER_NAMES = new Set(PTR_QUALIFIER_TOKEN_NAMES) +const FUNCTION_SPECIFIER_NAMES = new Set([ + 'KW_INLINE', 'KW___INLINE__', 'KW___INLINE', + 'KW__NORETURN', +]) + +function isSpecifierKw(name: string): boolean { + return STORAGE_CLASS_NAMES.has(name) || + TYPE_SPEC_KEYWORD_NAMES.has(name) || + TYPE_QUALIFIER_NAMES.has(name) || + FUNCTION_SPECIFIER_NAMES.has(name) || + name === 'TYPEDEF_NAME' +} + +// Find index of the matching closing punctuator for the opener at `from`. +// `open`/`close` are token names (e.g. 'PUNC_LPAREN', 'PUNC_RPAREN'). +// Returns -1 if unbalanced. +function matchClose( + tokens: Token[], from: number, open: string, close: string, +): number { + let depth = 0 + for (let i = from; i < tokens.length; i++) { + const n = tokens[i].name + if (n === open) depth++ + else if (n === close) { + depth-- + if (depth === 0) return i + } + } + return -1 +} + +// Locate the declared name within a declarator token slice. +// A declarator is: pointer* direct_declarator postfix* +// pointer := '*' qualifier* +// direct_decl := ID | '(' declarator ')' +// postfix := '[' ... ']' | '(' params ')' +// The first ID encountered after stripping pointers/qualifiers is the +// declared name; if a parenthesised subdeclarator opens first, recurse. +// Returns the name's source string, or null if no name is found. +function findDeclaredName(tokens: Token[]): string | null { + let i = 0 + while (i < tokens.length) { + const t = tokens[i] + if (TRIVIA_TOKEN_NAMES.has(t.name)) { i++; continue } + if (t.name === 'PUNC_STAR') { i++; continue } + if (PTR_QUALIFIER_TOKEN_NAMES.has(t.name)) { i++; continue } + // Compiler attribute or asm label inside declarators — skip + // balanced-paren attribute groups. + if (t.name === 'KW___ATTRIBUTE__' || t.name === 'KW___ATTRIBUTE' || + t.name === 'KW___ASM__' || t.name === 'KW___ASM' || t.name === 'KW_ASM' || + t.name === 'KW___DECLSPEC') { + // Expect '(' next; skip the balanced group. + let j = i + 1 + while (j < tokens.length && TRIVIA_TOKEN_NAMES.has(tokens[j].name)) j++ + if (j < tokens.length && tokens[j].name === 'PUNC_LPAREN') { + const close = matchClose(tokens, j, 'PUNC_LPAREN', 'PUNC_RPAREN') + if (close < 0) return null + i = close + 1 + continue + } + i++ + continue + } + if (t.name === 'PUNC_LPAREN') { + const close = matchClose(tokens, i, 'PUNC_LPAREN', 'PUNC_RPAREN') + if (close < 0) return null + // Distinguish a parenthesised subdeclarator from a function + // parameter list. A function parameter list starts with a type + // specifier or `void` or `)` (empty); a subdeclarator starts with + // `*`, `(`, an attribute spec, or an ordinary ID that ISN'T a + // typedef-name. + const inner = tokens.slice(i + 1, close) + const firstNonTrivia = inner.find((x) => !TRIVIA_TOKEN_NAMES.has(x.name)) + const looksLikeSubdeclarator = + !!firstNonTrivia && ( + firstNonTrivia.name === 'PUNC_STAR' || + firstNonTrivia.name === 'PUNC_LPAREN' || + firstNonTrivia.name === 'KW___ATTRIBUTE__' || + firstNonTrivia.name === 'KW___ATTRIBUTE' || + firstNonTrivia.name === 'ID' // ordinary ID is the declared name + ) + if (looksLikeSubdeclarator) { + const innerName = findDeclaredName(inner) + if (innerName) return innerName + } + // Otherwise treat as function postfix — skip past it. + i = close + 1 + continue + } + if (t.name === 'PUNC_LBRACKET') { + const close = matchClose(tokens, i, 'PUNC_LBRACKET', 'PUNC_RBRACKET') + if (close < 0) return null + i = close + 1 + continue + } + if (t.name === 'ID' || t.name === 'TYPEDEF_NAME') { + return t.src + } + return null + } + return null +} + +// Split the init-declarator-list portion of the token stream by top-level +// commas. Returns one token slice per declarator (initializer included). +function splitDeclarators(tokens: Token[]): Token[][] { + const out: Token[][] = [] + let start = 0 + let parenDepth = 0 + let bracketDepth = 0 + let braceDepth = 0 + for (let i = 0; i < tokens.length; i++) { + const n = tokens[i].name + if (n === 'PUNC_LPAREN') parenDepth++ + else if (n === 'PUNC_RPAREN') parenDepth-- + else if (n === 'PUNC_LBRACKET') bracketDepth++ + else if (n === 'PUNC_RBRACKET') bracketDepth-- + else if (n === 'PUNC_LBRACE') braceDepth++ + else if (n === 'PUNC_RBRACE') braceDepth-- + else if (n === 'PUNC_COMMA' && + parenDepth === 0 && bracketDepth === 0 && braceDepth === 0) { + out.push(tokens.slice(start, i)) + start = i + 1 + } + } + out.push(tokens.slice(start)) + return out +} + +// Slice an init-declarator at the first top-level `=`, returning just the +// declarator part (initializer is dropped from name-search). +function declaratorPart(tokens: Token[]): Token[] { + let parenDepth = 0 + let bracketDepth = 0 + for (let i = 0; i < tokens.length; i++) { + const n = tokens[i].name + if (n === 'PUNC_LPAREN') parenDepth++ + else if (n === 'PUNC_RPAREN') parenDepth-- + else if (n === 'PUNC_LBRACKET') bracketDepth++ + else if (n === 'PUNC_RBRACKET') bracketDepth-- + else if (n === 'PUNC_ASSIGN' && parenDepth === 0 && bracketDepth === 0) { + return tokens.slice(0, i) + } + } + return tokens +} + +// Identify the boundary between declaration-specifiers and the first +// declarator. Returns the index of the first non-specifier token. +// +// Specifiers are storage-classes, type-specifiers, type-qualifiers, +// function-specifiers, and a single TYPEDEF_NAME (after which any further +// ID is a declarator). struct/union/enum specifiers may also include a +// brace-balanced body — those are absorbed wholesale. +function findSpecBoundary(tokens: Token[]): number { + let i = 0 + let sawTypedefName = false + let sawTagSpec = false + while (i < tokens.length) { + const t = tokens[i] + if (TRIVIA_TOKEN_NAMES.has(t.name)) { i++; continue } + // After a TYPEDEF_NAME, a following ID belongs to the declarator. + if (t.name === 'TYPEDEF_NAME') { + if (sawTypedefName) return i + sawTypedefName = true + i++ + continue + } + if (t.name === 'KW_STRUCT' || t.name === 'KW_UNION' || t.name === 'KW_ENUM') { + sawTagSpec = true + i++ + // Optional tag name (ID). + while (i < tokens.length && TRIVIA_TOKEN_NAMES.has(tokens[i].name)) i++ + if (i < tokens.length && (tokens[i].name === 'ID' || tokens[i].name === 'TYPEDEF_NAME')) { + i++ + } + // Optional body. + while (i < tokens.length && TRIVIA_TOKEN_NAMES.has(tokens[i].name)) i++ + if (i < tokens.length && tokens[i].name === 'PUNC_LBRACE') { + const close = matchClose(tokens, i, 'PUNC_LBRACE', 'PUNC_RBRACE') + if (close < 0) return tokens.length + i = close + 1 + } + continue + } + if (isSpecifierKw(t.name) && t.name !== 'TYPEDEF_NAME') { + i++ + continue + } + // `__attribute__((...))` / `__declspec(...)` attached to the + // declaration: absorb as part of specifiers. + if (t.name === 'KW___ATTRIBUTE__' || t.name === 'KW___ATTRIBUTE' || + t.name === 'KW___DECLSPEC') { + i++ + while (i < tokens.length && TRIVIA_TOKEN_NAMES.has(tokens[i].name)) i++ + if (i < tokens.length && tokens[i].name === 'PUNC_LPAREN') { + const close = matchClose(tokens, i, 'PUNC_LPAREN', 'PUNC_RPAREN') + if (close < 0) return tokens.length + i = close + 1 + } + continue + } + return i + } + return i +} + function registerTypedefIfApplicable(tokens: Token[], ctx: Context): void { - // Strip trivia. - const filtered = tokens.filter( - (t) => - t.name !== 'TRIVIA_LINE_COMMENT' && - t.name !== 'TRIVIA_BLOCK_COMMENT' && - t.name !== 'TRIVIA_LINE_CONT' && - t.name !== '#SP', - ) + // Strip trivia for analysis (the original tokens still live on the AST). + const filtered = tokens.filter((t) => !TRIVIA_TOKEN_NAMES.has(t.name)) if (filtered.length < 3) return if (filtered[0].name !== 'KW_TYPEDEF') return const last = filtered[filtered.length - 1] if (last.name !== 'PUNC_SEMI') return - let i = filtered.length - 2 - if (filtered[i].name === 'ID' || filtered[i].name === 'TYPEDEF_NAME') { - const name = filtered[i].src - const cmeta = getCMeta(ctx) - cmeta.symbols.bindTypedef(name) - // Reclassify any already-lexed lookahead tokens that match this - // typedef name. Pre-fetched tokens live in ctx.t (the parser - // lookahead) and ctx.lex.pnt.token (the lexer queue). Mutating tin - // and name in place keeps subsequent grammar matches consistent - // with the freshly-registered typedef. - reclassifyAsTypedef(ctx, name) + // Drop the trailing `;` from the body we examine. + const body = filtered.slice(0, filtered.length - 1) + const specEnd = findSpecBoundary(body) + const declList = body.slice(specEnd) + if (declList.length === 0) return + const cmeta = getCMeta(ctx) + for (const decl of splitDeclarators(declList)) { + const justDecl = declaratorPart(decl) + const name = findDeclaredName(justDecl) + if (name) { + cmeta.symbols.bindTypedef(name) + reclassifyAsTypedef(ctx, name) + } + } +} + +// True when ctx.t0 (the next token to be consumed) is one of the tokens +// that unambiguously begin a new external declaration. Used by the +// chomper to decide that a top-level `}` was the end of a function body. +function startsNewExternalDeclaration(ctx: Context): boolean { + // Skip trivia in the lookahead. + let i = 0 + while (i < ctx.t.length) { + const tkn = ctx.t[i] + if (!tkn) break + if (TRIVIA_TOKEN_NAMES.has(tkn.name)) { i++; continue } + const n = tkn.name + if (n === '#ZZ') return true + if (n === 'PP_HASH') return true + if (n === 'PUNC_HASH') return true + if (STORAGE_CLASS_NAMES.has(n)) return true + if (TYPE_SPEC_KEYWORD_NAMES.has(n)) return true + if (TYPE_QUALIFIER_NAMES.has(n)) return true + if (FUNCTION_SPECIFIER_NAMES.has(n)) return true + if (n === 'KW___ATTRIBUTE__' || n === 'KW___ATTRIBUTE') return true + if (n === 'KW___DECLSPEC') return true + if (n === 'KW___EXTENSION__') return true + if (n === 'TYPEDEF_NAME') return true + // ID (could be a macro that expands to a declaration, or the + // declared name from `typedef struct { } S;`). Assume continuation. + return false } + return false } function reclassifyAsTypedef(ctx: Context, name: string): void { diff --git a/test/c.test.ts b/test/c.test.ts index b607698..a11c6a6 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -83,4 +83,97 @@ describe('c parser smoke', () => { ) }) + test('typedef multi-name: typedef int A, B, C;', () => { + // Each declared name must be registered as a typedef-name. + const src = 'typedef int A, B, C; A x; B y; C z;' + const out = j(src) + // Find the four follow-on declarations and confirm A/B/C lex as + // TYPEDEF_NAME. + const decls = out.children + assert.ok(decls.length >= 4) + const findToken = (decl: any, src: string) => + decl.children.find((c: any) => c.kind === 'token' && c.src === src) + assert.equal(findToken(decls[1], 'A')?.tname, 'TYPEDEF_NAME') + assert.equal(findToken(decls[2], 'B')?.tname, 'TYPEDEF_NAME') + assert.equal(findToken(decls[3], 'C')?.tname, 'TYPEDEF_NAME') + }) + + test('typedef with pointers: typedef int *PI;', () => { + const src = 'typedef int *PI; PI p;' + const out = j(src) + const second = out.children[1] + const piTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'PI') + assert.equal(piTok?.tname, 'TYPEDEF_NAME') + }) + + test('typedef array: typedef int Arr[10];', () => { + const src = 'typedef int Arr[10]; Arr a;' + const out = j(src) + const second = out.children[1] + const arrTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'Arr') + assert.equal(arrTok?.tname, 'TYPEDEF_NAME') + }) + + test('typedef function pointer: typedef int (*Fn)(int);', () => { + const src = 'typedef int (*Fn)(int); Fn f;' + const out = j(src) + const second = out.children[1] + const fnTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'Fn') + assert.equal(fnTok?.tname, 'TYPEDEF_NAME') + }) + + test('typedef of struct tag: typedef struct S T;', () => { + const src = 'typedef struct S T; T t;' + const out = j(src) + const second = out.children[1] + const tTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'T') + assert.equal(tTok?.tname, 'TYPEDEF_NAME') + }) + + test('typedef of struct with body: typedef struct { int x; } S;', () => { + const src = 'typedef struct { int x; } S; S s;' + const out = j(src) + // S is the second external_declaration's first identifier. + const second = out.children[1] + const sTok = second.children.find( + (c: any) => c.kind === 'token' && c.src === 'S' && c.tname === 'TYPEDEF_NAME', + ) + assert.ok(sTok, 'S should be registered as a typedef-name') + }) + + test('mixed typedef declarators: typedef int *p, q[3];', () => { + const src = 'typedef int *p, q[3]; p x; q y;' + const out = j(src) + const decls = out.children + const pTok = decls[1].children.find((c: any) => c.kind === 'token' && c.src === 'p') + const qTok = decls[2].children.find((c: any) => c.kind === 'token' && c.src === 'q') + assert.equal(pTok?.tname, 'TYPEDEF_NAME') + assert.equal(qTok?.tname, 'TYPEDEF_NAME') + }) + + test('function definition followed by another decl', () => { + const src = 'int main(void) { return 0; } int x;' + const out = j(src) + // Two external declarations: the function definition and `int x;`. + assert.equal(out.children.length, 2) + // First contains a `}` and a `return`. + const firstSrcs = out.children[0].children + .filter((c: any) => c.kind === 'token').map((t: any) => t.src) + assert.ok(firstSrcs.includes('return')) + assert.ok(firstSrcs.includes('}')) + // Second is `int x;`. + const secondSrcs = out.children[1].children + .filter((c: any) => c.kind === 'token').map((t: any) => t.src) + assert.deepEqual(secondSrcs, ['int', 'x', ';']) + }) + + test('compound literal initializer with braces does not prematurely terminate', () => { + const src = 'struct S x = { .a = 1, .b = 2 };' + const out = j(src) + assert.equal(out.children.length, 1) + const lastTok = out.children[0].children + .filter((c: any) => c.kind === 'token').slice(-1)[0] + assert.equal(lastTok.src, ';') + }) + }) From 834dd5bb89c4f77bc5bad274d7297caa0fbaee70 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 13:48:52 +0000 Subject: [PATCH 03/25] Slice 3: trivia preservation via sub-lex hook Move comment and line-continuation tokens into the IGNORE token set so the parser proper never sees them, then capture them in a sub-lex hook that attaches the buffered trivia to the next non-trivia token via tkn.use.leading. The chomper drains use.leading into the AST in source order ahead of each absorbed token, preserving comments verbatim without any grammar rule needing to mention them. - Split trivia into PRESERVE (block/line comments, line continuations) and DROP (whitespace, jsonic's #LN/#CM). Only PRESERVE flows to use.leading. - pendingTrivia lives on CMeta so it travels with parser state. - jsonic.sub({lex}) registers the hook once at plugin install. Tests: trivia ordering through declarations, line-continuation preservation, whitespace remains absent from the AST. --- src/c.ts | 69 +++++++++++++++++++++++++++++++++++++++++++++++--- src/symbols.ts | 6 +++++ test/c.test.ts | 40 +++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 4 deletions(-) diff --git a/src/c.ts b/src/c.ts index 699ccf5..f1e4735 100644 --- a/src/c.ts +++ b/src/c.ts @@ -100,6 +100,16 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { comment: { lex: false }, value: { lex: false }, match: { lex: true }, + // Trivia tokens are skipped by the parser (so grammar alts stay + // free of trivia clutter) but the sub-lex hook below still sees + // them and stashes them on the next non-trivia token's use.leading + // so source fidelity is preserved. + tokenSet: { + IGNORE: [ + '#SP', '#LN', '#CM', + 'TRIVIA_LINE_COMMENT', 'TRIVIA_BLOCK_COMMENT', 'TRIVIA_LINE_CONT', + ], + }, rule: { start: 'translation_unit', finish: false, @@ -135,6 +145,32 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { }, }) + // Sub-lex hook: every emitted token (including ignored ones) flows + // through here. Trivia tokens get pushed onto cmeta.pendingTrivia; + // the next non-trivia token receives them via use.leading. The + // chomper (and future grammar rules) drain use.leading into the AST + // so comments survive in source order even though IGNORE'd at + // parse time. + jsonic.sub({ + lex: (tkn: Token, _rule: Rule, ctx: Context) => { + if (!tkn || !tkn.isToken) return + const m = (ctx.meta as any).cmeta as CMeta + if (!m) return + // Comments and line continuations are preserved; whitespace and + // jsonic's #LN/#CM are silently dropped. + if (PRESERVE_TRIVIA_NAMES.has(tkn.name)) { + m.pendingTrivia.push(tkn) + return + } + if (DROP_TRIVIA_NAMES.has(tkn.name)) return + if (m.pendingTrivia.length > 0) { + ;(tkn as any).use = (tkn as any).use || {} + ;(tkn as any).use.leading = m.pendingTrivia + m.pendingTrivia = [] + } + }, + }) + // 2. Grammar. // // The translation unit holds a list of external_declaration nodes. @@ -201,6 +237,16 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { // The matched token lives in rule.o0 once the open-state alt // has fired; ctx.t0 at this point is the next lookahead token. const tkn = rule.o0 as Token + // Emit any leading trivia (comments, line continuations) the + // sub-lex hook stashed on tkn.use.leading, in source order, + // before the token itself. + const leading = (tkn as any).use && (tkn as any).use.leading + if (Array.isArray(leading)) { + for (const lt of leading) { + rule.node.children.push(tokenRef(lt)) + rule.k.tokens.push(lt) + } + } rule.k.tokens.push(tkn) rule.node.children.push(tokenRef(tkn)) rule.k.justClosedBrace = false @@ -271,7 +317,8 @@ function anyTokenSet(jsonic: Jsonic): number[] { 'ID', 'TYPEDEF_NAME', 'MACRO_NAME', 'LIT_INT', 'LIT_FLOAT', 'LIT_CHAR', 'LIT_STRING', 'LIT_HEADER_NAME', 'PP_HASH', 'PP_NEWLINE', 'PP_RAW', - 'TRIVIA_LINE_COMMENT', 'TRIVIA_BLOCK_COMMENT', 'TRIVIA_LINE_CONT', + // TRIVIA_* are IGNORE'd, not matched by alts. They flow into the + // AST via use.leading attachment in tokenRef expansion. ] for (const [pn] of PUNCTUATORS) names.push(pn) for (const kw of [...C23_KEYWORDS, ...EXT_KEYWORDS]) names.push(keywordTokenName(kw)!) @@ -279,12 +326,26 @@ function anyTokenSet(jsonic: Jsonic): number[] { return _anyTokenSetCache } -// Names of tokens that count as trivia (whitespace, comments, line cont). -const TRIVIA_TOKEN_NAMES = new Set([ - '#SP', '#LN', '#CM', +// Trivia whose source we want to keep in the AST (comments, line +// continuations) — captured by the sub-lex hook and re-emitted as token +// refs ahead of the next non-trivia token. +const PRESERVE_TRIVIA_NAMES = new Set([ 'TRIVIA_LINE_COMMENT', 'TRIVIA_BLOCK_COMMENT', 'TRIVIA_LINE_CONT', ]) +// Trivia we drop entirely from the AST (whitespace, raw newlines). +// Spans on real tokens still carry positional info. +const DROP_TRIVIA_NAMES = new Set([ + '#SP', '#LN', '#CM', +]) + +// Union, used by helpers that need to recognise any trivia regardless of +// whether it survives in the tree. +const TRIVIA_TOKEN_NAMES = new Set([ + ...PRESERVE_TRIVIA_NAMES, + ...DROP_TRIVIA_NAMES, +]) + // Type qualifiers in declarator pointer position. Used to skip past // `* const`, `* volatile`, etc. when locating a declared name. const PTR_QUALIFIER_TOKEN_NAMES = new Set([ diff --git a/src/symbols.ts b/src/symbols.ts index d0cc118..9992753 100644 --- a/src/symbols.ts +++ b/src/symbols.ts @@ -154,6 +154,11 @@ export interface CMeta { symbols: SymbolTable macros: MacroTable mode: LexMode + // Buffer of trivia tokens (comments, line continuations) emitted since + // the last non-trivia token. The sub-lex hook drains this buffer onto + // `tkn.use.leading` of each non-trivia token, so trivia stays attached + // to the token it precedes even though the parser sees it as IGNORE'd. + pendingTrivia: any[] } export function makeCMeta(): CMeta { @@ -161,5 +166,6 @@ export function makeCMeta(): CMeta { symbols: new SymbolTable(), macros: new MacroTable(), mode: { inDirective: false, expectHeaderName: false, directiveName: null }, + pendingTrivia: [], } } diff --git a/test/c.test.ts b/test/c.test.ts index a11c6a6..642c189 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -176,4 +176,44 @@ describe('c parser smoke', () => { assert.equal(lastTok.src, ';') }) + test('trivia: leading comments attach to next token', () => { + // Block and line comments before/between tokens must appear in the + // AST in source order. Whitespace is dropped (its position is still + // recoverable from token spans). + const src = '/* h */ int /* t */ x; // tail\nint y;' + const out = j(src) + const allTokenNames = out.children + .flatMap((d: any) => d.children) + .filter((c: any) => c.kind === 'token') + .map((t: any) => t.tname) + // The first declaration: leading block, KW_INT, leading block, ID, + // PUNC_SEMI. The line comment trails the first decl but attaches to + // the *next* non-trivia token (the second decl's KW_INT). + assert.ok(allTokenNames.includes('TRIVIA_BLOCK_COMMENT')) + assert.ok(allTokenNames.includes('TRIVIA_LINE_COMMENT')) + // Order check: the first block comment precedes KW_INT. + const idxBC = allTokenNames.indexOf('TRIVIA_BLOCK_COMMENT') + const idxKWI = allTokenNames.indexOf('KW_INT') + assert.ok(idxBC < idxKWI, 'block comment must precede int keyword') + }) + + test('trivia: line continuation is preserved as a token-ref', () => { + const src = 'int \\\nx;' + const out = j(src) + const tnames = out.children[0].children + .filter((c: any) => c.kind === 'token').map((t: any) => t.tname) + assert.ok(tnames.includes('TRIVIA_LINE_CONT')) + // The other tokens are still in the right order. + const real = tnames.filter((n: string) => !n.startsWith('TRIVIA_')) + assert.deepEqual(real, ['KW_INT', 'ID', 'PUNC_SEMI']) + }) + + test('whitespace is not emitted as a token', () => { + const src = 'int x ;' + const out = j(src) + const tnames = out.children[0].children + .filter((c: any) => c.kind === 'token').map((t: any) => t.tname) + assert.deepEqual(tnames, ['KW_INT', 'ID', 'PUNC_SEMI']) + }) + }) From 844e3388bcdc8d98248dc9fbd812151064d3cb74 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:02:33 +0000 Subject: [PATCH 04/25] Slice 4: structure external_declaration into a real CST Add a post-processing pass over the chomped token list (src/structure.ts) that produces structured concrete-syntax nodes for declarations and function definitions. Walking the resulting tree depth-first yields the original token sequence in order, so source fidelity is preserved while clients gain a shape they can actually navigate. The external_declaration close action now calls structureExternalDeclaration(tokens). On a clean parse it replaces the flat token-ref children with structured children: external_declaration { declKind: 'declaration' } declaration_specifiers struct_specifier|union_specifier|enum_specifier (with optional member_decl_list / enumerator_list still flat for now) attribute_spec (__attribute__((...)) / __declspec(...)) init_declarator_list init_declarator { declaredName } declarator pointer* (with qualifiers + attribute specs) direct_declarator { declaredName } array_postfix* function_postfix* asm_label? attribute_spec* '=' initializer? ',' init_declarator ... ';' external_declaration { declKind: 'function_definition' } declaration_specifiers declarator kr_declaration_list? (K&R old-style parameter declarations) compound_statement (body still flat tokens for now) The TokenStream class hides PRESERVED trivia from grammar decisions but emits the trivia tokens in order as siblings of the next real token's ref. This keeps comments and line continuations in the right place inside the structured tree. When structure can't recognise the shape (e.g. preprocessor lines, raw expression statements at top level) the chomper's flat token-ref list is retained and declKind is set to 'unknown'. Tests cover: simple int x = 1, multi-decl int a,b=2,c, pointer/array/ function declarators, function-definition with compound_statement, struct-with-body, enum with C23 fixed underlying type, and __attribute__ on a declaration. --- src/c.ts | 22 +- src/structure.ts | 655 +++++++++++++++++++++++++++++++++++++++++++++++ test/c.test.ts | 259 ++++++++++++------- 3 files changed, 837 insertions(+), 99 deletions(-) create mode 100644 src/structure.ts diff --git a/src/c.ts b/src/c.ts index f1e4735..08b3713 100644 --- a/src/c.ts +++ b/src/c.ts @@ -31,6 +31,7 @@ import { PUNCTUATORS, keywordTokenName, } from './tokens.js' +import { structureExternalDeclaration } from './structure.js' export interface COptions { // Reserved for future flags (strict mode, dialect selection, etc.) @@ -274,7 +275,7 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { s: ['#ZZ'], b: 1, a: (rule: Rule, ctx: Context) => { - registerTypedefIfApplicable(rule.k.tokens as Token[], ctx) + finalizeExternalDeclaration(rule, ctx) }, g: 'extdecl-finish-eof', }, @@ -286,7 +287,7 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { rule.k.justClosedBrace === true && startsNewExternalDeclaration(ctx), a: (rule: Rule, ctx: Context) => { - registerTypedefIfApplicable(rule.k.tokens as Token[], ctx) + finalizeExternalDeclaration(rule, ctx) }, g: 'extdecl-finish-block', }, @@ -294,7 +295,7 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { { c: (rule: Rule) => rule.k.terminated === true, a: (rule: Rule, ctx: Context) => { - registerTypedefIfApplicable(rule.k.tokens as Token[], ctx) + finalizeExternalDeclaration(rule, ctx) }, g: 'extdecl-finish', }, @@ -606,6 +607,21 @@ function registerTypedefIfApplicable(tokens: Token[], ctx: Context): void { } } +// Run after the chomper terminates an external declaration: register +// typedef-names and try to upgrade the flat token-ref list to a +// structured tree (declaration / function_definition / preprocessor). +function finalizeExternalDeclaration(rule: Rule, ctx: Context): void { + const tokens = rule.k.tokens as Token[] + registerTypedefIfApplicable(tokens, ctx) + const structured = structureExternalDeclaration(tokens) + if (structured) { + rule.node.children = structured.children + rule.node.declKind = structured.declKind + } else { + rule.node.declKind = 'unknown' + } +} + // True when ctx.t0 (the next token to be consumed) is one of the tokens // that unambiguously begin a new external declaration. Used by the // chomper to decide that a top-level `}` was the end of a function body. diff --git a/src/structure.ts b/src/structure.ts new file mode 100644 index 0000000..24cc3c6 --- /dev/null +++ b/src/structure.ts @@ -0,0 +1,655 @@ +/* Copyright (c) 2026 Richard Rodger and contributors, MIT License */ + +// Post-processing pass that turns the flat token list captured by the +// external_declaration chomper into a structured concrete-syntax tree. +// +// Approach: recursive-descent over a TokenStream that hides trivia from +// grammar-level decisions but emits trivia tokens in source order as +// siblings of the next real token. Each parse* function returns a node +// (or null) and advances the stream; the caller wires it into a parent +// node. +// +// This is a deliberate trade: we get a clean structured tree without +// reworking jsonic's grammar machinery for the full C grammar, at the +// cost of doing the parse twice (once to chomp the tokens, once here to +// structure them). Future slices may collapse this into in-line jsonic +// rules; for now the approach lets each C construct live as a small +// composable function. + +import type { Token } from 'jsonic' + +export interface Span { + start: number; end: number; line: number; col: number +} + +export interface CTokenRef { + kind: 'token' + tname: string + src: string + span: Span +} + +export interface CNode { + kind: string + span: Span + children: Array + trivia: { leading: CTokenRef[]; trailing: CTokenRef[] } + [extra: string]: any +} + +const PRESERVED_TRIVIA = new Set([ + 'TRIVIA_LINE_COMMENT', 'TRIVIA_BLOCK_COMMENT', 'TRIVIA_LINE_CONT', +]) + +const STORAGE_CLASS = new Set([ + 'KW_TYPEDEF', 'KW_EXTERN', 'KW_STATIC', 'KW_AUTO', 'KW_REGISTER', + 'KW__THREAD_LOCAL', 'KW_THREAD_LOCAL', 'KW_CONSTEXPR', + 'KW___THREAD', +]) + +const TYPE_QUALIFIER = new Set([ + 'KW_CONST', 'KW_VOLATILE', 'KW_RESTRICT', 'KW__ATOMIC', + 'KW___CONST__', 'KW___CONST', + 'KW___VOLATILE__', 'KW___VOLATILE', + 'KW___RESTRICT__', 'KW___RESTRICT', +]) + +const FUNCTION_SPECIFIER = new Set([ + 'KW_INLINE', 'KW___INLINE__', 'KW___INLINE', + 'KW__NORETURN', +]) + +const SIMPLE_TYPE_SPEC = new Set([ + 'KW_VOID', 'KW_CHAR', 'KW_SHORT', 'KW_INT', 'KW_LONG', 'KW_FLOAT', + 'KW_DOUBLE', 'KW_SIGNED', 'KW_UNSIGNED', 'KW_BOOL', 'KW__BOOL', + 'KW__COMPLEX', 'KW__IMAGINARY', + 'KW___SIGNED__', 'KW___SIGNED', + 'KW___INT8', 'KW___INT16', 'KW___INT32', 'KW___INT64', +]) + +const ATTRIBUTE_OPENERS = new Set([ + 'KW___ATTRIBUTE__', 'KW___ATTRIBUTE', + 'KW___DECLSPEC', +]) + +function isSpecifierStart(name: string): boolean { + return STORAGE_CLASS.has(name) || + TYPE_QUALIFIER.has(name) || + FUNCTION_SPECIFIER.has(name) || + SIMPLE_TYPE_SPEC.has(name) || + ATTRIBUTE_OPENERS.has(name) || + name === 'KW_STRUCT' || name === 'KW_UNION' || name === 'KW_ENUM' || + name === 'KW_TYPEOF' || name === 'KW_TYPEOF_UNQUAL' || + name === 'KW___TYPEOF__' || name === 'KW___TYPEOF' || + name === 'KW__BITINT' || + name === 'KW_ALIGNAS' || name === 'KW__ALIGNAS' || + name === 'KW___EXTENSION__' || + name === 'TYPEDEF_NAME' +} + +function tokenRef(t: Token): CTokenRef { + return { + kind: 'token', + tname: t.name, + src: t.src, + span: { start: t.sI, end: t.sI + t.len, line: t.rI, col: t.cI }, + } +} + +function makeNode(kind: string, startSpan?: Span): CNode { + return { + kind, + span: startSpan ?? { start: 0, end: 0, line: 1, col: 1 }, + children: [], + trivia: { leading: [], trailing: [] }, + } +} + +// Clone-ish span from a token. +function spanOf(t: Token): Span { + return { start: t.sI, end: t.sI + t.len, line: t.rI, col: t.cI } +} + +// ---- TokenStream ---------------------------------------------------- + +export class TokenStream { + i: number = 0 + constructor(public tokens: Token[]) {} + + // Skip past trivia and return the next real token, or null at end. + peek(off: number = 0): Token | null { + let i = this.i + let seen = 0 + while (i < this.tokens.length) { + const t = this.tokens[i] + if (PRESERVED_TRIVIA.has(t.name)) { i++; continue } + if (seen === off) return t + seen++ + i++ + } + return null + } + + peekName(off: number = 0): string | null { + return this.peek(off)?.name ?? null + } + + done(): boolean { return this.peek() === null } + + // Consume the next real token along with any preceding trivia. + // Returns the trivia refs followed by the real token's ref. + take(): { trivia: CTokenRef[]; tkn: Token; ref: CTokenRef } | null { + const trivia: CTokenRef[] = [] + while (this.i < this.tokens.length) { + const t = this.tokens[this.i] + if (PRESERVED_TRIVIA.has(t.name)) { + trivia.push(tokenRef(t)) + this.i++ + continue + } + this.i++ + return { trivia, tkn: t, ref: tokenRef(t) } + } + return null + } + + // Push the trivia and the just-taken real token onto a node's children. + takeInto(node: CNode): Token | null { + const taken = this.take() + if (!taken) return null + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + return taken.tkn + } + + mark(): number { return this.i } + restore(m: number) { this.i = m } +} + +// ---- Helpers for balanced punctuator skipping ----------------------- + +function consumeBalanced( + ts: TokenStream, node: CNode, + open: string, close: string, +): boolean { + if (ts.peekName() !== open) return false + ts.takeInto(node) // open + let depth = 1 + while (depth > 0 && !ts.done()) { + const n = ts.peekName() + if (n === open) depth++ + else if (n === close) depth-- + ts.takeInto(node) + } + return depth === 0 +} + +// ---- Specifier parsing ---------------------------------------------- + +export function parseDeclarationSpecifiers(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn || !isSpecifierStart(startTkn.name)) return null + const node = makeNode('declaration_specifiers', spanOf(startTkn)) + + // The legal sequence permits a single TYPEDEF_NAME (after which any + // further ID belongs to the declarator). Track it to avoid confusing + // `T x` with `T int`-style nonsense. + let sawTypedefName = false + + while (true) { + const tkn = ts.peek() + if (!tkn) break + const n = tkn.name + + if (n === 'TYPEDEF_NAME') { + if (sawTypedefName) break + sawTypedefName = true + ts.takeInto(node) + continue + } + if (STORAGE_CLASS.has(n) || TYPE_QUALIFIER.has(n) || + FUNCTION_SPECIFIER.has(n) || SIMPLE_TYPE_SPEC.has(n) || + n === 'KW___EXTENSION__' || + n === 'KW_TYPEOF' || n === 'KW_TYPEOF_UNQUAL' || + n === 'KW___TYPEOF__' || n === 'KW___TYPEOF' || + n === 'KW__BITINT' || + n === 'KW_ALIGNAS' || n === 'KW__ALIGNAS') { + // typeof/_BitInt/alignas have a parenthesised argument list — fold + // it into the specifier node. + ts.takeInto(node) + if ((n === 'KW_TYPEOF' || n === 'KW_TYPEOF_UNQUAL' || + n === 'KW___TYPEOF__' || n === 'KW___TYPEOF' || + n === 'KW__BITINT' || + n === 'KW_ALIGNAS' || n === 'KW__ALIGNAS') && + ts.peekName() === 'PUNC_LPAREN') { + consumeBalanced(ts, node, 'PUNC_LPAREN', 'PUNC_RPAREN') + } + continue + } + if (ATTRIBUTE_OPENERS.has(n)) { + const attr = parseAttributeSpec(ts) + if (attr) node.children.push(attr) + else ts.takeInto(node) + continue + } + if (n === 'KW_STRUCT' || n === 'KW_UNION') { + const sus = parseStructOrUnionSpec(ts) + if (sus) node.children.push(sus) + continue + } + if (n === 'KW_ENUM') { + const en = parseEnumSpec(ts) + if (en) node.children.push(en) + continue + } + break + } + + if (node.children.length === 0) return null + return node +} + +export function parseAttributeSpec(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn || !ATTRIBUTE_OPENERS.has(startTkn.name)) return null + const node = makeNode('attribute_spec', spanOf(startTkn)) + ts.takeInto(node) // __attribute__ / __declspec + if (ts.peekName() === 'PUNC_LPAREN') { + consumeBalanced(ts, node, 'PUNC_LPAREN', 'PUNC_RPAREN') + } + return node +} + +export function parseStructOrUnionSpec(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn || (startTkn.name !== 'KW_STRUCT' && startTkn.name !== 'KW_UNION')) return null + const kind = startTkn.name === 'KW_STRUCT' ? 'struct_specifier' : 'union_specifier' + const node = makeNode(kind, spanOf(startTkn)) + ts.takeInto(node) // 'struct' or 'union' + + // Optional attribute spec between keyword and tag/body. + while (ts.peek() && ATTRIBUTE_OPENERS.has(ts.peekName()!)) { + const a = parseAttributeSpec(ts) + if (a) node.children.push(a) + } + + // Optional tag identifier. + const next = ts.peek() + if (next && (next.name === 'ID' || next.name === 'TYPEDEF_NAME')) { + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.tagName = taken.tkn.src + } + + // Optional body. Members are kept opaque in this slice; future work + // splits them into struct_declaration nodes. + if (ts.peekName() === 'PUNC_LBRACE') { + const body = makeNode('member_decl_list', spanOf(ts.peek()!)) + consumeBalanced(ts, body, 'PUNC_LBRACE', 'PUNC_RBRACE') + node.children.push(body) + } + + return node +} + +export function parseEnumSpec(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn || startTkn.name !== 'KW_ENUM') return null + const node = makeNode('enum_specifier', spanOf(startTkn)) + ts.takeInto(node) // 'enum' + + while (ts.peek() && ATTRIBUTE_OPENERS.has(ts.peekName()!)) { + const a = parseAttributeSpec(ts) + if (a) node.children.push(a) + } + + const next = ts.peek() + if (next && (next.name === 'ID' || next.name === 'TYPEDEF_NAME')) { + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.tagName = taken.tkn.src + } + + // C23: optional ': type-specifier' for fixed-underlying-type enums. + if (ts.peekName() === 'PUNC_COLON') { + ts.takeInto(node) + const ts2 = parseDeclarationSpecifiers(ts) + if (ts2) node.children.push(ts2) + } + + // Optional body. + if (ts.peekName() === 'PUNC_LBRACE') { + const body = makeNode('enumerator_list', spanOf(ts.peek()!)) + consumeBalanced(ts, body, 'PUNC_LBRACE', 'PUNC_RBRACE') + node.children.push(body) + } + + return node +} + +// ---- Declarator parsing --------------------------------------------- + +export function parseDeclarator(ts: TokenStream, abstract = false): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const node = makeNode(abstract ? 'abstract_declarator' : 'declarator', spanOf(startTkn)) + + // Pointer prefix: '*' qualifier* (repeated). + while (ts.peekName() === 'PUNC_STAR') { + const ptr = makeNode('pointer', spanOf(ts.peek()!)) + ts.takeInto(ptr) // '*' + while (true) { + const n = ts.peekName() + if (n && (TYPE_QUALIFIER.has(n) || + n === 'KW___PTR32' || n === 'KW___PTR64' || + n === 'KW___UNALIGNED')) { + ts.takeInto(ptr) + continue + } + if (n && ATTRIBUTE_OPENERS.has(n)) { + const a = parseAttributeSpec(ts) + if (a) ptr.children.push(a); else break + continue + } + break + } + node.children.push(ptr) + } + + // direct declarator + const dd = parseDirectDeclarator(ts, abstract) + if (!dd) { + if (abstract && node.children.length > 0) return node + return node.children.length > 0 ? node : null + } + node.children.push(dd) + if (dd.declaredName) node.declaredName = dd.declaredName + return node +} + +function parseDirectDeclarator(ts: TokenStream, abstract: boolean): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const node = makeNode(abstract ? 'direct_abstract_declarator' : 'direct_declarator', spanOf(startTkn)) + + // Primary: ID, or '(' declarator ')', or empty (abstract). + const n0 = ts.peekName() + if (n0 === 'ID') { + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.declaredName = taken.tkn.src + } else if (n0 === 'PUNC_LPAREN') { + // Could be parenthesised subdeclarator OR the start of a function + // postfix (parameter list) on an abstract declarator. Disambiguate: + // peek the first non-trivia token inside `(`. + const m = ts.mark() + ts.takeInto(node) // '(' + const inner = ts.peek() + if (inner && (inner.name === 'PUNC_STAR' || + inner.name === 'PUNC_LPAREN' || + inner.name === 'ID' || + ATTRIBUTE_OPENERS.has(inner.name))) { + // Subdeclarator + const sub = parseDeclarator(ts, abstract) + if (sub) { + node.children.push(sub) + if (sub.declaredName) node.declaredName = sub.declaredName + } + // Expect ')' + if (ts.peekName() === 'PUNC_RPAREN') ts.takeInto(node) + } else { + // Looked like a function parameter list directly — rewind and let + // postfix loop pick it up. + ts.restore(m) + } + } else if (!abstract) { + return null + } + + // Postfixes: '[' ... ']' or '(' parameter_list ')'. + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PUNC_LBRACKET') { + const arr = makeNode('array_postfix', spanOf(ts.peek()!)) + consumeBalanced(ts, arr, 'PUNC_LBRACKET', 'PUNC_RBRACKET') + node.children.push(arr) + continue + } + if (n === 'PUNC_LPAREN') { + const fn = makeNode('function_postfix', spanOf(ts.peek()!)) + consumeBalanced(ts, fn, 'PUNC_LPAREN', 'PUNC_RPAREN') + node.children.push(fn) + continue + } + break + } + + if (node.children.length === 0 && !abstract) return null + return node +} + +// ---- init-declarator-list ------------------------------------------- + +export function parseInitDeclaratorList(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const node = makeNode('init_declarator_list', spanOf(startTkn)) + + const first = parseInitDeclarator(ts) + if (!first) return null + node.children.push(first) + + while (ts.peekName() === 'PUNC_COMMA') { + ts.takeInto(node) // ',' + const next = parseInitDeclarator(ts) + if (!next) break + node.children.push(next) + } + return node +} + +export function parseInitDeclarator(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const decl = parseDeclarator(ts, false) + if (!decl) return null + // Optional asm-label and attribute-specifiers between declarator and `=`. + const node = makeNode('init_declarator', spanOf(startTkn)) + node.children.push(decl) + if (decl.declaredName) node.declaredName = decl.declaredName + + while (true) { + const n = ts.peekName() + if (!n) break + if (n === 'KW___ASM__' || n === 'KW___ASM' || n === 'KW_ASM') { + const asmNode = makeNode('asm_label', spanOf(ts.peek()!)) + ts.takeInto(asmNode) + if (ts.peekName() === 'PUNC_LPAREN') { + consumeBalanced(ts, asmNode, 'PUNC_LPAREN', 'PUNC_RPAREN') + } + node.children.push(asmNode) + continue + } + if (ATTRIBUTE_OPENERS.has(n)) { + const a = parseAttributeSpec(ts) + if (a) node.children.push(a); else break + continue + } + break + } + + if (ts.peekName() === 'PUNC_ASSIGN') { + ts.takeInto(node) // '=' + const init = parseInitializer(ts) + if (init) node.children.push(init) + } + return node +} + +// Initializer is opaque-balanced for now: a single token, or a brace +// group, or anything until a top-level `,` or `;` or `}`. +export function parseInitializer(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const node = makeNode('initializer', spanOf(startTkn)) + if (ts.peekName() === 'PUNC_LBRACE') { + consumeBalanced(ts, node, 'PUNC_LBRACE', 'PUNC_RBRACE') + return node + } + // Otherwise, absorb up to the first top-level `,` `;` or `}`. + let parenD = 0, bracketD = 0 + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PUNC_LPAREN') { parenD++; ts.takeInto(node); continue } + if (n === 'PUNC_RPAREN') { + if (parenD === 0) break + parenD--; ts.takeInto(node); continue + } + if (n === 'PUNC_LBRACKET') { bracketD++; ts.takeInto(node); continue } + if (n === 'PUNC_RBRACKET') { + if (bracketD === 0) break + bracketD--; ts.takeInto(node); continue + } + if (parenD === 0 && bracketD === 0 && + (n === 'PUNC_COMMA' || n === 'PUNC_SEMI' || n === 'PUNC_RBRACE')) break + ts.takeInto(node) + } + return node +} + +// ---- compound statement --------------------------------------------- + +// Function body. Currently kept as a flat token list (children = token +// refs of every token in the block). Future slices will recurse into +// statements. +export function parseCompoundStatement(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn || startTkn.name !== 'PUNC_LBRACE') return null + const node = makeNode('compound_statement', spanOf(startTkn)) + consumeBalanced(ts, node, 'PUNC_LBRACE', 'PUNC_RBRACE') + return node +} + +// ---- top-level dispatch --------------------------------------------- + +// Parse a single external_declaration from the token list. Returns the +// structured children to install on the external_declaration node, plus +// the recognised declKind. If parsing fails (unrecognised structure), +// returns null and the caller should retain the flat token-ref children. +export function structureExternalDeclaration(tokens: Token[]): { + declKind: 'declaration' | 'function_definition' | 'declaration_list' | 'unknown' + children: Array +} | null { + // Filter out the trailing/preceding non-token entries; we only consume + // jsonic Tokens here. + const ts = new TokenStream(tokens) + if (ts.done()) return null + + // Preprocessor lines start with PP_HASH and end with PP_NEWLINE; the + // preprocessor slice handles them later. For now just bail. + if (ts.peekName() === 'PP_HASH') return null + + // Specifiers (optional). + const specs = parseDeclarationSpecifiers(ts) + + // If no specifiers AND no declarator follows (e.g. just `;`), bail. + if (!specs && ts.peekName() !== 'ID' && ts.peekName() !== 'PUNC_STAR' && + ts.peekName() !== 'PUNC_LPAREN') { + return null + } + + // The init-declarator-list is optional (e.g. `struct S;` has none). + const declaratorsStart = ts.mark() + const decls = parseInitDeclaratorList(ts) + + // After declarator list, expect either `;` (declaration) or `{` (function + // definition with body), or a comma-separated init-decl-list already + // consumed and the trailing punctuation. + const tail = ts.peekName() + + const out: Array = [] + if (specs) out.push(specs) + + if (tail === 'PUNC_SEMI') { + if (decls) out.push(decls) + // Consume the ';' and any trailing tokens (shouldn't be any, but if + // there are, append them as raw refs to preserve fidelity). + while (!ts.done()) { + const taken = ts.take() + if (!taken) break + for (const tr of taken.trivia) out.push(tr) + out.push(taken.ref) + } + return { declKind: 'declaration', children: out } + } + + if (tail === 'PUNC_LBRACE') { + // Function definition. The init-declarator-list parse may have + // produced one declarator with no initializer — that's the + // function's declarator. + if (decls) { + // Promote the single init_declarator to a plain declarator if it + // has no initializer (idiomatic for function definitions). + const single = decls.children.length === 1 ? decls.children[0] as CNode : null + if (single && single.kind === 'init_declarator' && + single.children.length === 1 && + (single.children[0] as CNode).kind === 'declarator') { + out.push(single.children[0] as CNode) + } else { + out.push(decls) + } + } + const body = parseCompoundStatement(ts) + if (body) out.push(body) + // Append any unexpected trailing content. + while (!ts.done()) { + const taken = ts.take() + if (!taken) break + for (const tr of taken.trivia) out.push(tr) + out.push(taken.ref) + } + return { declKind: 'function_definition', children: out } + } + + // K&R-style function definition: declarator IDs followed by + // declaration-list before `{`. Detect by finding `{` later. + if (tail && tail !== 'PUNC_SEMI') { + // Defensive: if the next tokens before any `{` look like a + // declaration-list, capture them as a nested declaration_list node + // and keep going until `{`. + const krStart = ts.mark() + let sawBrace = false + while (!ts.done()) { + if (ts.peekName() === 'PUNC_LBRACE') { sawBrace = true; break } + // Just consume one token at a time; we'll structure later. + const taken = ts.take() + if (!taken) break + } + if (sawBrace) { + ts.restore(krStart) + const krList = makeNode('kr_declaration_list', spanOf(ts.peek()!)) + while (!ts.done() && ts.peekName() !== 'PUNC_LBRACE') { + ts.takeInto(krList) + } + if (decls) out.push(decls) + out.push(krList) + const body = parseCompoundStatement(ts) + if (body) out.push(body) + while (!ts.done()) { + const taken = ts.take() + if (!taken) break + for (const tr of taken.trivia) out.push(tr) + out.push(taken.ref) + } + return { declKind: 'function_definition', children: out } + } + ts.restore(krStart) + } + + // Couldn't structure cleanly — give up. + // (Caller falls back to the flat token-ref list.) + return null +} diff --git a/test/c.test.ts b/test/c.test.ts index 642c189..96be935 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -8,212 +8,279 @@ import { C } from '../dist/c.js' const j = Jsonic.make().use(C, {}) +// Walk a CST node depth-first and yield its token-refs in source order. +function walkTokens(node: any): any[] { + const out: any[] = [] + const visit = (n: any) => { + if (!n) return + if (n.kind === 'token') { out.push(n); return } + if (Array.isArray(n.children)) { + for (const c of n.children) visit(c) + } + } + visit(node) + return out +} + +function findTokenBySrc(node: any, src: string): any { + return walkTokens(node).find((t) => t.src === src) +} + +function tokenSrcs(node: any): string[] { + return walkTokens(node).map((t) => t.src) +} + +function tokenNames(node: any): string[] { + return walkTokens(node).map((t) => t.tname) +} + +// Find the first descendant of `node` whose .kind matches. +function findKind(node: any, kind: string): any { + if (!node) return null + if (node.kind === kind) return node + if (Array.isArray(node.children)) { + for (const c of node.children) { + const hit = findKind(c, kind) + if (hit) return hit + } + } + return null +} + describe('c parser smoke', () => { test('lex: tokenises a simple typedef declaration', () => { - // We don't yet drive a parse end-to-end with rich grammar, so this - // test exercises the lex pipeline only by asking for tokens. const src = 'typedef int T;' - // Use jsonic.parse for the real entrypoint when grammar is ready; - // for now we just check it doesn't throw and produces *something*. const out = j(src) assert.ok(out, 'parse should produce a translation unit') assert.equal(out.kind, 'translation_unit') }) test('lex: tokenises arithmetic and identifiers', () => { - // Sanity: int x = 1 + 2; — currently only a primary initializer is - // accepted, so we use a single literal initializer. const src = 'int x = 42;' const out = j(src) assert.equal(out.kind, 'translation_unit') }) test('typedef registration: T becomes a typedef-name', () => { - // After `typedef int T;`, the next `T` should be classified by the - // identifier matcher as TYPEDEF_NAME thanks to symbol-table feedback. const src = 'typedef int T;\nT x;\n' const out = j(src) assert.equal(out.kind, 'translation_unit') assert.ok(out.children.length >= 2, 'expected two external declarations') - const second = out.children[1] - // The second external_declaration's children are token-refs in source - // order. Find the token whose src is 'T' and confirm it was emitted - // as a TYPEDEF_NAME, not an ID. - const tTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'T') - assert.ok(tTok, 'expected to find a token with src "T"') - assert.equal(tTok.tname, 'TYPEDEF_NAME', - 'after typedef registration, T must lex as TYPEDEF_NAME') - // And confirm `x` is still an ordinary ID (it was never typedef'd). - const xTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'x') - assert.ok(xTok, 'expected to find a token with src "x"') - assert.equal(xTok.tname, 'ID', 'x must lex as a plain ID') + const tTok = findTokenBySrc(out.children[1], 'T') + assert.ok(tTok, 'expected a token with src "T"') + assert.equal(tTok.tname, 'TYPEDEF_NAME') + const xTok = findTokenBySrc(out.children[1], 'x') + assert.equal(xTok.tname, 'ID') }) test('keyword vs identifier boundary: int_value is one ID, not int + _value', () => { const src = 'int int_value;' const out = j(src) const decl = out.children[0] - const tokens = decl.children.filter((c: any) => c.kind === 'token') - const srcs = tokens.map((t: any) => t.src) - assert.deepEqual(srcs, ['int', 'int_value', ';']) - assert.equal(tokens[0].tname, 'KW_INT') - assert.equal(tokens[1].tname, 'ID') + assert.deepEqual(tokenSrcs(decl), ['int', 'int_value', ';']) + const realToks = walkTokens(decl).filter((t) => !t.tname.startsWith('TRIVIA_')) + assert.equal(realToks[0].tname, 'KW_INT') + assert.equal(realToks[1].tname, 'ID') }) test('lex preserves block and line comments as trivia tokens', () => { const src = '/* hi */ int x; // trail\n' const out = j(src) - // A line comment after the ; is consumed by the next iteration's - // chomp; a block comment before the decl is its first child token. assert.equal(out.kind, 'translation_unit') const blockTokenAnywhere = out.children - .flatMap((d: any) => d.children) - .find((c: any) => c.kind === 'token' && c.tname === 'TRIVIA_BLOCK_COMMENT') + .flatMap((d: any) => walkTokens(d)) + .find((c: any) => c.tname === 'TRIVIA_BLOCK_COMMENT') assert.ok(blockTokenAnywhere, 'block comment must survive in the AST') }) test('punctuator dispatch: 3-char and 2-char operators', () => { const src = 'a >>= 1;' const out = j(src) - const tokens = out.children[0].children.filter((c: any) => c.kind === 'token') - assert.deepEqual( - tokens.map((t: any) => t.tname), - ['ID', 'PUNC_RSHIFT_ASSIGN', 'LIT_INT', 'PUNC_SEMI'], - ) + // `a >>= 1;` parses as an expression statement at the top level — but + // our top-level chomp treats it as a declaration shape. Either way, + // the four tokens are preserved. + const names = tokenNames(out.children[0]).filter((n) => !n.startsWith('TRIVIA_')) + assert.deepEqual(names, ['ID', 'PUNC_RSHIFT_ASSIGN', 'LIT_INT', 'PUNC_SEMI']) }) test('typedef multi-name: typedef int A, B, C;', () => { - // Each declared name must be registered as a typedef-name. const src = 'typedef int A, B, C; A x; B y; C z;' const out = j(src) - // Find the four follow-on declarations and confirm A/B/C lex as - // TYPEDEF_NAME. const decls = out.children assert.ok(decls.length >= 4) - const findToken = (decl: any, src: string) => - decl.children.find((c: any) => c.kind === 'token' && c.src === src) - assert.equal(findToken(decls[1], 'A')?.tname, 'TYPEDEF_NAME') - assert.equal(findToken(decls[2], 'B')?.tname, 'TYPEDEF_NAME') - assert.equal(findToken(decls[3], 'C')?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(decls[1], 'A')?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(decls[2], 'B')?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(decls[3], 'C')?.tname, 'TYPEDEF_NAME') }) test('typedef with pointers: typedef int *PI;', () => { const src = 'typedef int *PI; PI p;' const out = j(src) - const second = out.children[1] - const piTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'PI') - assert.equal(piTok?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(out.children[1], 'PI')?.tname, 'TYPEDEF_NAME') }) test('typedef array: typedef int Arr[10];', () => { const src = 'typedef int Arr[10]; Arr a;' const out = j(src) - const second = out.children[1] - const arrTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'Arr') - assert.equal(arrTok?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(out.children[1], 'Arr')?.tname, 'TYPEDEF_NAME') }) test('typedef function pointer: typedef int (*Fn)(int);', () => { const src = 'typedef int (*Fn)(int); Fn f;' const out = j(src) - const second = out.children[1] - const fnTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'Fn') - assert.equal(fnTok?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(out.children[1], 'Fn')?.tname, 'TYPEDEF_NAME') }) test('typedef of struct tag: typedef struct S T;', () => { const src = 'typedef struct S T; T t;' const out = j(src) - const second = out.children[1] - const tTok = second.children.find((c: any) => c.kind === 'token' && c.src === 'T') - assert.equal(tTok?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(out.children[1], 'T')?.tname, 'TYPEDEF_NAME') }) test('typedef of struct with body: typedef struct { int x; } S;', () => { const src = 'typedef struct { int x; } S; S s;' const out = j(src) - // S is the second external_declaration's first identifier. - const second = out.children[1] - const sTok = second.children.find( - (c: any) => c.kind === 'token' && c.src === 'S' && c.tname === 'TYPEDEF_NAME', - ) + const sTok = walkTokens(out.children[1]) + .find((t: any) => t.src === 'S' && t.tname === 'TYPEDEF_NAME') assert.ok(sTok, 'S should be registered as a typedef-name') }) test('mixed typedef declarators: typedef int *p, q[3];', () => { const src = 'typedef int *p, q[3]; p x; q y;' const out = j(src) - const decls = out.children - const pTok = decls[1].children.find((c: any) => c.kind === 'token' && c.src === 'p') - const qTok = decls[2].children.find((c: any) => c.kind === 'token' && c.src === 'q') - assert.equal(pTok?.tname, 'TYPEDEF_NAME') - assert.equal(qTok?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(out.children[1], 'p')?.tname, 'TYPEDEF_NAME') + assert.equal(findTokenBySrc(out.children[2], 'q')?.tname, 'TYPEDEF_NAME') }) test('function definition followed by another decl', () => { const src = 'int main(void) { return 0; } int x;' const out = j(src) - // Two external declarations: the function definition and `int x;`. assert.equal(out.children.length, 2) - // First contains a `}` and a `return`. - const firstSrcs = out.children[0].children - .filter((c: any) => c.kind === 'token').map((t: any) => t.src) + const firstSrcs = tokenSrcs(out.children[0]) assert.ok(firstSrcs.includes('return')) assert.ok(firstSrcs.includes('}')) - // Second is `int x;`. - const secondSrcs = out.children[1].children - .filter((c: any) => c.kind === 'token').map((t: any) => t.src) - assert.deepEqual(secondSrcs, ['int', 'x', ';']) + assert.deepEqual(tokenSrcs(out.children[1]), ['int', 'x', ';']) }) test('compound literal initializer with braces does not prematurely terminate', () => { const src = 'struct S x = { .a = 1, .b = 2 };' const out = j(src) assert.equal(out.children.length, 1) - const lastTok = out.children[0].children - .filter((c: any) => c.kind === 'token').slice(-1)[0] - assert.equal(lastTok.src, ';') + const realToks = walkTokens(out.children[0]) + .filter((t) => !t.tname.startsWith('TRIVIA_')) + assert.equal(realToks[realToks.length - 1].src, ';') }) test('trivia: leading comments attach to next token', () => { - // Block and line comments before/between tokens must appear in the - // AST in source order. Whitespace is dropped (its position is still - // recoverable from token spans). const src = '/* h */ int /* t */ x; // tail\nint y;' const out = j(src) - const allTokenNames = out.children - .flatMap((d: any) => d.children) - .filter((c: any) => c.kind === 'token') - .map((t: any) => t.tname) - // The first declaration: leading block, KW_INT, leading block, ID, - // PUNC_SEMI. The line comment trails the first decl but attaches to - // the *next* non-trivia token (the second decl's KW_INT). - assert.ok(allTokenNames.includes('TRIVIA_BLOCK_COMMENT')) - assert.ok(allTokenNames.includes('TRIVIA_LINE_COMMENT')) - // Order check: the first block comment precedes KW_INT. - const idxBC = allTokenNames.indexOf('TRIVIA_BLOCK_COMMENT') - const idxKWI = allTokenNames.indexOf('KW_INT') + const allNames = out.children.flatMap((d: any) => tokenNames(d)) + assert.ok(allNames.includes('TRIVIA_BLOCK_COMMENT')) + assert.ok(allNames.includes('TRIVIA_LINE_COMMENT')) + const idxBC = allNames.indexOf('TRIVIA_BLOCK_COMMENT') + const idxKWI = allNames.indexOf('KW_INT') assert.ok(idxBC < idxKWI, 'block comment must precede int keyword') }) test('trivia: line continuation is preserved as a token-ref', () => { const src = 'int \\\nx;' const out = j(src) - const tnames = out.children[0].children - .filter((c: any) => c.kind === 'token').map((t: any) => t.tname) + const tnames = tokenNames(out.children[0]) assert.ok(tnames.includes('TRIVIA_LINE_CONT')) - // The other tokens are still in the right order. - const real = tnames.filter((n: string) => !n.startsWith('TRIVIA_')) + const real = tnames.filter((n) => !n.startsWith('TRIVIA_')) assert.deepEqual(real, ['KW_INT', 'ID', 'PUNC_SEMI']) }) test('whitespace is not emitted as a token', () => { const src = 'int x ;' const out = j(src) - const tnames = out.children[0].children - .filter((c: any) => c.kind === 'token').map((t: any) => t.tname) + const tnames = tokenNames(out.children[0]) + .filter((n) => !n.startsWith('TRIVIA_')) assert.deepEqual(tnames, ['KW_INT', 'ID', 'PUNC_SEMI']) }) + // ---- Structural CST shape (slice 4) ---------------------------------- + + test('structure: simple declaration produces declaration_specifiers + init_declarator_list + ;', () => { + const src = 'int x = 1;' + const out = j(src) + const ext = out.children[0] + assert.equal(ext.declKind, 'declaration') + const specs = findKind(ext, 'declaration_specifiers') + assert.ok(specs) + assert.deepEqual(tokenSrcs(specs), ['int']) + const idl = findKind(ext, 'init_declarator_list') + assert.ok(idl) + const id = findKind(idl, 'init_declarator') + assert.ok(id) + assert.equal(id.declaredName, 'x') + const init = findKind(id, 'initializer') + assert.ok(init) + assert.deepEqual(tokenSrcs(init), ['1']) + }) + + test('structure: multiple declarators in one declaration', () => { + const src = 'int a, b = 2, c;' + const out = j(src) + const idl = findKind(out.children[0], 'init_declarator_list') + const ids = (idl?.children || []).filter((c: any) => c.kind === 'init_declarator') + assert.equal(ids.length, 3) + assert.deepEqual(ids.map((d: any) => d.declaredName), ['a', 'b', 'c']) + }) + + test('structure: pointer/array/function declarators', () => { + const src = 'int *p; int a[10]; int f(int x);' + const out = j(src) + const decls = out.children + // pointer + const declP = decls[0] + assert.ok(findKind(declP, 'pointer')) + assert.equal(findKind(declP, 'init_declarator').declaredName, 'p') + // array + const declA = decls[1] + assert.ok(findKind(declA, 'array_postfix')) + assert.equal(findKind(declA, 'init_declarator').declaredName, 'a') + // function declaration + const declF = decls[2] + assert.ok(findKind(declF, 'function_postfix')) + assert.equal(findKind(declF, 'init_declarator').declaredName, 'f') + }) + + test('structure: function definition has compound_statement', () => { + const src = 'int main(void) { return 0; }' + const out = j(src) + const ext = out.children[0] + assert.equal(ext.declKind, 'function_definition') + assert.ok(findKind(ext, 'declaration_specifiers')) + assert.ok(findKind(ext, 'declarator')) + assert.ok(findKind(ext, 'compound_statement')) + }) + + test('structure: struct definition with body', () => { + const src = 'struct S { int x; int y; };' + const out = j(src) + const ss = findKind(out.children[0], 'struct_specifier') + assert.ok(ss) + assert.equal(ss.tagName, 'S') + assert.ok(findKind(ss, 'member_decl_list')) + }) + + test('structure: enum with C23 fixed underlying type', () => { + const src = 'enum E : int { A, B, C };' + const out = j(src) + const en = findKind(out.children[0], 'enum_specifier') + assert.ok(en) + assert.equal(en.tagName, 'E') + assert.ok(findKind(en, 'enumerator_list')) + }) + + test('structure: __attribute__ on a declaration', () => { + const src = '__attribute__((noreturn)) void die(void);' + const out = j(src) + const ext = out.children[0] + assert.equal(ext.declKind, 'declaration') + assert.ok(findKind(ext, 'attribute_spec')) + }) + }) From 43611d1318a2f69eb68cbc3b9c31464fe0334701 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:04:08 +0000 Subject: [PATCH 05/25] Slice 5: structure struct/union/enum bodies into typed members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the opaque brace-balanced member_decl_list / enumerator_list of slice 4 with proper member parsing. struct/union bodies now contain struct_declaration nodes, each with: - specifier_qualifier_list (declaration_specifiers reused, renamed) - struct_declarator_list of struct_declarator nodes - trailing ';' struct_declarator carries: - the declarator (with declaredName) - optional bitfield_width (`: const-expr`) - optional trailing attribute_spec This handles `struct S { unsigned f : 1; int : 7; int n; };` cleanly, including anonymous bitfields. static_assert at member level (C23 + GCC) becomes a static_assert_declaration node. enum bodies now contain enumerator nodes, each with: - declaredName - optional [[…]] / __attribute__((…)) attribute_spec (C23) - optional initializer (constant-expression, opaque for now) The trailing comma after the last enumerator is preserved. Tests: three-field struct, bitfield + anonymous bitfield, enum with initializer and trailing comma. --- src/structure.ts | 202 +++++++++++++++++++++++++++++++++++++++++++++-- test/c.test.ts | 48 +++++++++++ 2 files changed, 245 insertions(+), 5 deletions(-) diff --git a/src/structure.ts b/src/structure.ts index 24cc3c6..841e990 100644 --- a/src/structure.ts +++ b/src/structure.ts @@ -282,17 +282,143 @@ export function parseStructOrUnionSpec(ts: TokenStream): CNode | null { node.tagName = taken.tkn.src } - // Optional body. Members are kept opaque in this slice; future work - // splits them into struct_declaration nodes. + // Optional body — split into struct_declaration nodes. if (ts.peekName() === 'PUNC_LBRACE') { const body = makeNode('member_decl_list', spanOf(ts.peek()!)) - consumeBalanced(ts, body, 'PUNC_LBRACE', 'PUNC_RBRACE') + ts.takeInto(body) // '{' + while (!ts.done() && ts.peekName() !== 'PUNC_RBRACE') { + const member = parseStructDeclaration(ts) + if (member) { + body.children.push(member) + } else { + // Defensive: take one token to avoid infinite loop. + ts.takeInto(body) + } + } + if (ts.peekName() === 'PUNC_RBRACE') ts.takeInto(body) // '}' node.children.push(body) } return node } +// struct_declaration: +// specifier_qualifier_list struct_declarator_list? ';' +// | static_assert_declaration +// | ';' (empty member, GCC extension) +export function parseStructDeclaration(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + + // static_assert at member level. + const n0 = startTkn.name + if (n0 === 'KW_STATIC_ASSERT' || n0 === 'KW__STATIC_ASSERT') { + const sa = makeNode('static_assert_declaration', spanOf(startTkn)) + ts.takeInto(sa) + if (ts.peekName() === 'PUNC_LPAREN') { + consumeBalanced(ts, sa, 'PUNC_LPAREN', 'PUNC_RPAREN') + } + if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(sa) + return sa + } + + // Empty member: just `;`. + if (n0 === 'PUNC_SEMI') { + const empty = makeNode('struct_declaration', spanOf(startTkn)) + ts.takeInto(empty) + return empty + } + + const node = makeNode('struct_declaration', spanOf(startTkn)) + // specifier_qualifier_list — same shape as declaration_specifiers but + // without storage classes and function specifiers. We reuse the + // common parser; bogus storage-classes inside a struct are a semantic + // error, not a parse error. + const sql = parseDeclarationSpecifiers(ts) + if (sql) { + sql.kind = 'specifier_qualifier_list' + node.children.push(sql) + } + + // Optional struct_declarator_list. + if (ts.peekName() !== 'PUNC_SEMI' && !ts.done()) { + const sdl = parseStructDeclaratorList(ts) + if (sdl) node.children.push(sdl) + } + + if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(node) + return node +} + +// struct_declarator_list: +// struct_declarator (',' struct_declarator)* +// struct_declarator: +// declarator +// | declarator? ':' constant_expression (bitfield) +export function parseStructDeclaratorList(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const node = makeNode('struct_declarator_list', spanOf(startTkn)) + const first = parseStructDeclarator(ts) + if (!first) return null + node.children.push(first) + while (ts.peekName() === 'PUNC_COMMA') { + ts.takeInto(node) + const next = parseStructDeclarator(ts) + if (!next) break + node.children.push(next) + } + return node +} + +export function parseStructDeclarator(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const node = makeNode('struct_declarator', spanOf(startTkn)) + + // Optional declarator (absent in `: 4` anonymous bitfields). + if (ts.peekName() !== 'PUNC_COLON') { + const d = parseDeclarator(ts, false) + if (d) { + node.children.push(d) + if (d.declaredName) node.declaredName = d.declaredName + } + } + + // Optional bitfield width: `:` constant-expression. + if (ts.peekName() === 'PUNC_COLON') { + const bf = makeNode('bitfield_width', spanOf(ts.peek()!)) + ts.takeInto(bf) // ':' + // Constant-expression — opaque until top-level `,` or `;`. + let parenD = 0, bracketD = 0 + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PUNC_LPAREN') { parenD++; ts.takeInto(bf); continue } + if (n === 'PUNC_RPAREN') { + if (parenD === 0) break + parenD--; ts.takeInto(bf); continue + } + if (n === 'PUNC_LBRACKET') { bracketD++; ts.takeInto(bf); continue } + if (n === 'PUNC_RBRACKET') { + if (bracketD === 0) break + bracketD--; ts.takeInto(bf); continue + } + if (parenD === 0 && bracketD === 0 && + (n === 'PUNC_COMMA' || n === 'PUNC_SEMI')) break + ts.takeInto(bf) + } + node.children.push(bf) + } + + // Optional trailing attribute spec. + while (ts.peek() && ATTRIBUTE_OPENERS.has(ts.peekName()!)) { + const a = parseAttributeSpec(ts) + if (a) node.children.push(a); else break + } + + return node.children.length > 0 ? node : null +} + export function parseEnumSpec(ts: TokenStream): CNode | null { const startTkn = ts.peek() if (!startTkn || startTkn.name !== 'KW_ENUM') return null @@ -319,16 +445,82 @@ export function parseEnumSpec(ts: TokenStream): CNode | null { if (ts2) node.children.push(ts2) } - // Optional body. + // Optional body — split into enumerator nodes. if (ts.peekName() === 'PUNC_LBRACE') { const body = makeNode('enumerator_list', spanOf(ts.peek()!)) - consumeBalanced(ts, body, 'PUNC_LBRACE', 'PUNC_RBRACE') + ts.takeInto(body) // '{' + while (!ts.done() && ts.peekName() !== 'PUNC_RBRACE') { + const e = parseEnumerator(ts) + if (e) body.children.push(e) + else ts.takeInto(body) + if (ts.peekName() === 'PUNC_COMMA') ts.takeInto(body) + } + if (ts.peekName() === 'PUNC_RBRACE') ts.takeInto(body) // '}' node.children.push(body) } return node } +// enumerator: enumeration-constant attribute-specifier-seq? ('=' const-expr)? +export function parseEnumerator(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const n = startTkn.name + if (n !== 'ID' && n !== 'TYPEDEF_NAME' && n !== 'MACRO_NAME') return null + const node = makeNode('enumerator', spanOf(startTkn)) + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.declaredName = taken.tkn.src + + // Optional [[attribute]] in C23 / __attribute__ in GCC. C23 uses + // double-bracketed attributes which our token stream sees as two + // PUNC_LBRACKETs in a row. + while (true) { + const nn = ts.peekName() + if (nn && ATTRIBUTE_OPENERS.has(nn)) { + const a = parseAttributeSpec(ts) + if (a) node.children.push(a); else break + continue + } + if (nn === 'PUNC_LBRACKET' && ts.peekName(1) === 'PUNC_LBRACKET') { + // Consume the C23 [[ ... ]] attribute group as one balanced unit. + const attr = makeNode('attribute_spec', spanOf(ts.peek()!)) + consumeBalanced(ts, attr, 'PUNC_LBRACKET', 'PUNC_RBRACKET') + consumeBalanced(ts, attr, 'PUNC_LBRACKET', 'PUNC_RBRACKET') + node.children.push(attr) + continue + } + break + } + + if (ts.peekName() === 'PUNC_ASSIGN') { + ts.takeInto(node) // '=' + // Constant-expression — opaque until top-level `,` or `}`. + const init = makeNode('initializer', spanOf(ts.peek() || startTkn)) + let parenD = 0, bracketD = 0 + while (!ts.done()) { + const nn = ts.peekName() + if (nn === 'PUNC_LPAREN') { parenD++; ts.takeInto(init); continue } + if (nn === 'PUNC_RPAREN') { + if (parenD === 0) break + parenD--; ts.takeInto(init); continue + } + if (nn === 'PUNC_LBRACKET') { bracketD++; ts.takeInto(init); continue } + if (nn === 'PUNC_RBRACKET') { + if (bracketD === 0) break + bracketD--; ts.takeInto(init); continue + } + if (parenD === 0 && bracketD === 0 && + (nn === 'PUNC_COMMA' || nn === 'PUNC_RBRACE')) break + ts.takeInto(init) + } + node.children.push(init) + } + return node +} + // ---- Declarator parsing --------------------------------------------- export function parseDeclarator(ts: TokenStream, abstract = false): CNode | null { diff --git a/test/c.test.ts b/test/c.test.ts index 96be935..575a62d 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -283,4 +283,52 @@ describe('c parser smoke', () => { assert.ok(findKind(ext, 'attribute_spec')) }) + // ---- Structural members (slice 5) ------------------------------------ + + test('structure: struct members parsed as struct_declaration nodes', () => { + const src = 'struct S { int x; char *p; double d; };' + const out = j(src) + const ml = findKind(out.children[0], 'member_decl_list') + assert.ok(ml) + const members = ml.children.filter((c: any) => c.kind === 'struct_declaration') + assert.equal(members.length, 3) + // Each member has a specifier_qualifier_list and a struct_declarator_list. + for (const m of members) { + assert.ok(findKind(m, 'specifier_qualifier_list')) + assert.ok(findKind(m, 'struct_declarator_list')) + } + // Names of declared fields: + const fieldNames = members.map((m: any) => + findKind(m, 'struct_declarator')?.declaredName) + assert.deepEqual(fieldNames, ['x', 'p', 'd']) + }) + + test('structure: bitfield members are recognised', () => { + const src = 'struct B { unsigned int flag : 1; int : 7; int n; };' + const out = j(src) + const ml = findKind(out.children[0], 'member_decl_list') + const sds = ml.children.filter((c: any) => c.kind === 'struct_declaration') + assert.equal(sds.length, 3) + // Member 0: declarator + bitfield_width + const m0 = sds[0] + assert.ok(findKind(m0, 'bitfield_width')) + assert.equal(findKind(m0, 'struct_declarator')?.declaredName, 'flag') + // Member 1: anonymous bitfield, no declared name. + const m1 = sds[1] + assert.ok(findKind(m1, 'bitfield_width')) + assert.equal(findKind(m1, 'struct_declarator')?.declaredName, undefined) + }) + + test('structure: enum members parsed as enumerator nodes', () => { + const src = 'enum E { A, B = 2, C, };' + const out = j(src) + const el = findKind(out.children[0], 'enumerator_list') + assert.ok(el) + const enums = el.children.filter((c: any) => c.kind === 'enumerator') + assert.equal(enums.length, 3) + assert.deepEqual(enums.map((e: any) => e.declaredName), ['A', 'B', 'C']) + // B has an initializer. + assert.ok(findKind(enums[1], 'initializer')) + }) + }) From 32eccde2a8960ababcee929eac4671bb03b2c078 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:06:09 +0000 Subject: [PATCH 06/25] Slice 6: parse statements inside compound_statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the flat-token compound_statement of slice 4 with proper block-item parsing. A compound_statement now contains: - declaration nodes (when the head is a specifier or static_assert) - statement nodes, dispatched by leading token Statement kinds modelled (each preserves all source tokens): - if_statement (with paren_condition + then-stmt + optional else) - switch_statement - while_statement - do_statement (do … while (…) ;) - for_statement (for_controls captures the parenthesised header) - jump_statement (goto/continue/break/return; jumpKind set) - labeled_statement (case / default / label; labelKind/labelName) - expression_statement - compound_statement (recursive) - asm_statement (GCC __asm__ / asm with optional qualifiers) - preprocessor_line (PP_HASH … PP_NEWLINE, opaque) Also factored out parseDeclaration so the same shape used at the top level is reused inside blocks. Tests: function with mixed decl+expr+return body, if/else+while+for in one body, switch with case+default labels, goto+label round trip, do/while. --- src/structure.ts | 307 ++++++++++++++++++++++++++++++++++++++++++++++- test/c.test.ts | 77 ++++++++++++ 2 files changed, 379 insertions(+), 5 deletions(-) diff --git a/src/structure.ts b/src/structure.ts index 841e990..31e4a8f 100644 --- a/src/structure.ts +++ b/src/structure.ts @@ -712,16 +712,313 @@ export function parseInitializer(ts: TokenStream): CNode | null { return node } -// ---- compound statement --------------------------------------------- +// ---- compound statement & statements -------------------------------- -// Function body. Currently kept as a flat token list (children = token -// refs of every token in the block). Future slices will recurse into -// statements. +// '{' (declaration | statement)* '}' export function parseCompoundStatement(ts: TokenStream): CNode | null { const startTkn = ts.peek() if (!startTkn || startTkn.name !== 'PUNC_LBRACE') return null const node = makeNode('compound_statement', spanOf(startTkn)) - consumeBalanced(ts, node, 'PUNC_LBRACE', 'PUNC_RBRACE') + ts.takeInto(node) // '{' + while (!ts.done() && ts.peekName() !== 'PUNC_RBRACE') { + const item = parseBlockItem(ts) + if (item) { + node.children.push(item) + } else { + // Defensive: avoid infinite loop on unrecognised tokens. + ts.takeInto(node) + } + } + if (ts.peekName() === 'PUNC_RBRACE') ts.takeInto(node) // '}' + return node +} + +// Either a declaration or a statement. +export function parseBlockItem(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + + // Preprocessor lines aren't structured at this level — fall through + // to a raw_token to preserve them as opaque siblings. + if (startTkn.name === 'PP_HASH') { + return takePreprocessorLine(ts) + } + + // Declaration if the head is a specifier, attribute, or the C23 + // `static_assert` keyword (or its underscore form). + const n0 = startTkn.name + if (isSpecifierStart(n0) || + n0 === 'KW_STATIC_ASSERT' || n0 === 'KW__STATIC_ASSERT') { + const decl = parseDeclaration(ts) + if (decl) return decl + } + + return parseStatement(ts) +} + +// Re-usable inner-declaration parser: declaration_specifiers +// init_declarator_list? `;`. Returns a `declaration` node, mirroring +// the shape produced for top-level declarations by structureExternal- +// Declaration. +export function parseDeclaration(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + + // static_assert is its own declaration shape. + if (startTkn.name === 'KW_STATIC_ASSERT' || + startTkn.name === 'KW__STATIC_ASSERT') { + const sa = makeNode('static_assert_declaration', spanOf(startTkn)) + ts.takeInto(sa) + if (ts.peekName() === 'PUNC_LPAREN') { + consumeBalanced(ts, sa, 'PUNC_LPAREN', 'PUNC_RPAREN') + } + if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(sa) + return sa + } + + const node = makeNode('declaration', spanOf(startTkn)) + const specs = parseDeclarationSpecifiers(ts) + if (specs) node.children.push(specs) + if (ts.peekName() !== 'PUNC_SEMI' && !ts.done()) { + const idl = parseInitDeclaratorList(ts) + if (idl) node.children.push(idl) + } + if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(node) + return node.children.length > 0 ? node : null +} + +// Top-level statement dispatch. +export function parseStatement(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const n0 = startTkn.name + + if (n0 === 'PUNC_LBRACE') return parseCompoundStatement(ts) + if (n0 === 'PUNC_SEMI') { + const e = makeNode('expression_statement', spanOf(startTkn)) + ts.takeInto(e) + return e + } + + if (n0 === 'KW_IF') return parseIfStatement(ts) + if (n0 === 'KW_SWITCH') return parseSwitchStatement(ts) + if (n0 === 'KW_WHILE') return parseWhileStatement(ts) + if (n0 === 'KW_DO') return parseDoStatement(ts) + if (n0 === 'KW_FOR') return parseForStatement(ts) + + if (n0 === 'KW_GOTO' || n0 === 'KW_CONTINUE' || + n0 === 'KW_BREAK' || n0 === 'KW_RETURN') { + return parseJumpStatement(ts) + } + + if (n0 === 'KW_CASE' || n0 === 'KW_DEFAULT') { + return parseLabeledStatement(ts) + } + + // ID ':' starts a labeled statement; otherwise it's an expression + // statement. + if (n0 === 'ID' && ts.peekName(1) === 'PUNC_COLON') { + return parseLabeledStatement(ts) + } + + // GCC: `__asm__ (…);` as a statement. + if (n0 === 'KW___ASM__' || n0 === 'KW___ASM' || n0 === 'KW_ASM') { + return parseAsmStatement(ts) + } + + return parseExpressionStatement(ts) +} + +function parseIfStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('if_statement', spanOf(startTkn)) + ts.takeInto(node) // 'if' + if (ts.peekName() === 'PUNC_LPAREN') { + const cond = makeNode('paren_condition', spanOf(ts.peek()!)) + consumeBalanced(ts, cond, 'PUNC_LPAREN', 'PUNC_RPAREN') + node.children.push(cond) + } + const thenStmt = parseStatement(ts) + if (thenStmt) node.children.push(thenStmt) + if (ts.peekName() === 'KW_ELSE') { + ts.takeInto(node) // 'else' + const elseStmt = parseStatement(ts) + if (elseStmt) node.children.push(elseStmt) + } + return node +} + +function parseSwitchStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('switch_statement', spanOf(startTkn)) + ts.takeInto(node) // 'switch' + if (ts.peekName() === 'PUNC_LPAREN') { + const cond = makeNode('paren_condition', spanOf(ts.peek()!)) + consumeBalanced(ts, cond, 'PUNC_LPAREN', 'PUNC_RPAREN') + node.children.push(cond) + } + const body = parseStatement(ts) + if (body) node.children.push(body) + return node +} + +function parseWhileStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('while_statement', spanOf(startTkn)) + ts.takeInto(node) // 'while' + if (ts.peekName() === 'PUNC_LPAREN') { + const cond = makeNode('paren_condition', spanOf(ts.peek()!)) + consumeBalanced(ts, cond, 'PUNC_LPAREN', 'PUNC_RPAREN') + node.children.push(cond) + } + const body = parseStatement(ts) + if (body) node.children.push(body) + return node +} + +function parseDoStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('do_statement', spanOf(startTkn)) + ts.takeInto(node) // 'do' + const body = parseStatement(ts) + if (body) node.children.push(body) + if (ts.peekName() === 'KW_WHILE') ts.takeInto(node) + if (ts.peekName() === 'PUNC_LPAREN') { + const cond = makeNode('paren_condition', spanOf(ts.peek()!)) + consumeBalanced(ts, cond, 'PUNC_LPAREN', 'PUNC_RPAREN') + node.children.push(cond) + } + if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(node) + return node +} + +function parseForStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('for_statement', spanOf(startTkn)) + ts.takeInto(node) // 'for' + if (ts.peekName() === 'PUNC_LPAREN') { + // The for-controls live inside (), separated by exactly two `;`s. + // We capture them as a single for_controls node and let downstream + // consumers split them; preserves all tokens with no semantic loss. + const ctl = makeNode('for_controls', spanOf(ts.peek()!)) + consumeBalanced(ts, ctl, 'PUNC_LPAREN', 'PUNC_RPAREN') + node.children.push(ctl) + } + const body = parseStatement(ts) + if (body) node.children.push(body) + return node +} + +function parseJumpStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('jump_statement', spanOf(startTkn)) + node.jumpKind = startTkn.src + ts.takeInto(node) // jump keyword + // Consume tokens up to the terminating `;`. + while (!ts.done() && ts.peekName() !== 'PUNC_SEMI') { + ts.takeInto(node) + } + if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(node) + return node +} + +function parseLabeledStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('labeled_statement', spanOf(startTkn)) + if (startTkn.name === 'KW_CASE') { + node.labelKind = 'case' + ts.takeInto(node) // 'case' + // const-expr until top-level `:` + let parenD = 0 + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PUNC_LPAREN') { parenD++; ts.takeInto(node); continue } + if (n === 'PUNC_RPAREN') { + if (parenD === 0) break + parenD--; ts.takeInto(node); continue + } + if (parenD === 0 && n === 'PUNC_COLON') break + ts.takeInto(node) + } + } else if (startTkn.name === 'KW_DEFAULT') { + node.labelKind = 'default' + ts.takeInto(node) // 'default' + } else { + // ID ':' + node.labelKind = 'label' + node.labelName = startTkn.src + ts.takeInto(node) // ID + } + if (ts.peekName() === 'PUNC_COLON') ts.takeInto(node) + // The labeled body is a statement. + const inner = parseStatement(ts) + if (inner) node.children.push(inner) + return node +} + +function parseExpressionStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('expression_statement', spanOf(startTkn)) + // Capture every token up to the terminating `;` at depth 0. + let parenD = 0, bracketD = 0, braceD = 0 + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PUNC_LPAREN') { parenD++; ts.takeInto(node); continue } + if (n === 'PUNC_RPAREN') { + if (parenD === 0) break + parenD--; ts.takeInto(node); continue + } + if (n === 'PUNC_LBRACKET') { bracketD++; ts.takeInto(node); continue } + if (n === 'PUNC_RBRACKET') { + if (bracketD === 0) break + bracketD--; ts.takeInto(node); continue + } + if (n === 'PUNC_LBRACE') { braceD++; ts.takeInto(node); continue } + if (n === 'PUNC_RBRACE') { + if (braceD === 0) break + braceD--; ts.takeInto(node); continue + } + if (parenD === 0 && bracketD === 0 && braceD === 0 && + n === 'PUNC_SEMI') break + ts.takeInto(node) + } + if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(node) + return node +} + +function parseAsmStatement(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('asm_statement', spanOf(startTkn)) + ts.takeInto(node) // asm keyword + // Optional volatile/inline/goto qualifiers. + while (true) { + const n = ts.peekName() + if (n === 'KW_VOLATILE' || n === 'KW___VOLATILE__' || n === 'KW___VOLATILE' || + n === 'KW_INLINE' || n === 'KW___INLINE__' || n === 'KW___INLINE' || + n === 'KW_GOTO') { + ts.takeInto(node) + continue + } + break + } + if (ts.peekName() === 'PUNC_LPAREN') { + consumeBalanced(ts, node, 'PUNC_LPAREN', 'PUNC_RPAREN') + } + if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(node) + return node +} + +function takePreprocessorLine(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('preprocessor_line', spanOf(startTkn)) + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PP_NEWLINE') { + ts.takeInto(node) + break + } + ts.takeInto(node) + } return node } diff --git a/test/c.test.ts b/test/c.test.ts index 575a62d..afebf22 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -331,4 +331,81 @@ describe('c parser smoke', () => { assert.ok(findKind(enums[1], 'initializer')) }) + // ---- Statements (slice 6) ------------------------------------------- + + test('statements: function body decomposes into block items', () => { + const src = 'int f(void) { int x = 1; x = x + 1; return x; }' + const out = j(src) + const cs = findKind(out.children[0], 'compound_statement') + assert.ok(cs) + const items = cs.children.filter( + (c: any) => c.kind === 'declaration' || c.kind === 'expression_statement' || + c.kind === 'jump_statement', + ) + assert.equal(items.length, 3) + assert.equal(items[0].kind, 'declaration') + assert.equal(items[1].kind, 'expression_statement') + assert.equal(items[2].kind, 'jump_statement') + assert.equal(items[2].jumpKind, 'return') + }) + + test('statements: if/else, while, for', () => { + const src = ` + int f(int n) { + if (n > 0) return 1; else return 0; + while (n--) ; + for (int i = 0; i < 10; i++) n += i; + } + ` + const out = j(src) + const cs = findKind(out.children[0], 'compound_statement') + assert.ok(findKind(cs, 'if_statement')) + assert.ok(findKind(cs, 'while_statement')) + assert.ok(findKind(cs, 'for_statement')) + assert.ok(findKind(cs, 'for_controls')) + }) + + test('statements: switch with case and default labels', () => { + const src = ` + int f(int x) { + switch (x) { + case 1: return 1; + case 2: return 2; + default: return 0; + } + } + ` + const out = j(src) + const sw = findKind(out.children[0], 'switch_statement') + assert.ok(sw) + // Inside the switch body's compound_statement we expect three labeled + // statements with appropriate labelKind tags. + const labels: any[] = [] + const visit = (n: any) => { + if (!n) return + if (n.kind === 'labeled_statement') labels.push(n) + if (Array.isArray(n.children)) for (const c of n.children) visit(c) + } + visit(sw) + assert.equal(labels.length, 3) + assert.deepEqual(labels.map((l: any) => l.labelKind), ['case', 'case', 'default']) + }) + + test('statements: goto + label', () => { + const src = 'void f(void) { goto out; out: return; }' + const out = j(src) + const cs = findKind(out.children[0], 'compound_statement') + const jmp = findKind(cs, 'jump_statement') + assert.equal(jmp.jumpKind, 'goto') + const lbl = findKind(cs, 'labeled_statement') + assert.equal(lbl.labelKind, 'label') + assert.equal(lbl.labelName, 'out') + }) + + test('statements: do/while', () => { + const src = 'void f(void) { do { } while (0); }' + const out = j(src) + assert.ok(findKind(out.children[0], 'do_statement')) + }) + }) From fc8599fa545d7e57f2c26b8677596b8daa5f7d60 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:09:20 +0000 Subject: [PATCH 07/25] Slice 7: structure preprocessor directives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each #-line on the input now becomes its own external_declaration containing one structured directive node, instead of being absorbed into the surrounding code by the chomper. Directive node kinds and their structured fields: - include_directive { includeForm, headerKind, headerName } - define_directive { macroName, macroKind ('object-like' | 'function-like'), macroParams?, macroVariadic? } - undef_directive { macroName } - conditional_directive { directive: 'if'|'ifdef'|'ifndef'|'elif'| 'elifdef'|'elifndef'|'else'|'endif' } - pragma_directive (opaque body) - error_directive (opaque body) - warning_directive (opaque body) - line_directive (opaque body) - unknown_directive (any other #-form) The function-like distinction in #define checks adjacency: only `NAME(` with no whitespace between produces a function-like macro. Parameter list parsing pulls out parameter names and detects the variadic ellipsis. The chomper now terminates an external_declaration at PP_NEWLINE when the first non-trivia token is PP_HASH, so a directive line plus a following declaration land as two separate external_declarations instead of one giant chomp. Define/undef directives populate ctx.meta.cmeta.macros so future slices can tag macro-call sites. Conditional groups (#if … #endif) are intentionally left as a flat sequence of directive + declaration nodes for now; collapsing them into a single nested group with branches comes in a follow-up slice. Tests: angled and quoted #include, object-like and function-like #define (with variadic), #if/#endif sequencing, #pragma/#error, #undef. --- src/c.ts | 41 +++++++++ src/structure.ts | 210 +++++++++++++++++++++++++++++++++++++++++++++-- test/c.test.ts | 68 +++++++++++++++ 3 files changed, 312 insertions(+), 7 deletions(-) diff --git a/src/c.ts b/src/c.ts index 08b3713..b14ffde 100644 --- a/src/c.ts +++ b/src/c.ts @@ -265,6 +265,12 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { else if (tkn.name === 'PUNC_SEMI' && rule.k.depth === 0) { rule.k.terminated = true } + else if (tkn.name === 'PP_NEWLINE' && rule.k.depth === 0 && + firstNonTriviaIs(rule.k.tokens, 'PP_HASH')) { + // Directive line ends here — each preprocessor directive + // is its own external_declaration. + rule.k.terminated = true + } }, g: 'extdecl-tok', }, @@ -617,11 +623,46 @@ function finalizeExternalDeclaration(rule: Rule, ctx: Context): void { if (structured) { rule.node.children = structured.children rule.node.declKind = structured.declKind + registerMacrosFromTree(rule.node, ctx) } else { rule.node.declKind = 'unknown' } } +// Walk a freshly-structured node and register any define_directive +// macros into cmeta.macros (and #undef removes them). The walk only +// touches the top-level external_declaration's tree — surrounding +// translation_unit accumulation visits each child in order, so macro +// state evolves as the parse progresses. +function registerMacrosFromTree(node: any, ctx: Context): void { + const cmeta = (ctx.meta as any).cmeta as CMeta + if (!cmeta) return + const visit = (n: any) => { + if (!n) return + if (n.kind === 'define_directive' && n.macroName) { + cmeta.macros.define({ + name: n.macroName, + isFunctionLike: n.macroKind === 'function-like', + params: n.macroParams, + variadic: !!n.macroVariadic, + }) + } else if (n.kind === 'undef_directive' && n.macroName) { + cmeta.macros.undefine(n.macroName) + } + if (Array.isArray(n.children)) for (const c of n.children) visit(c) + } + visit(node) +} + +// True iff the first non-trivia entry in `tokens` has the given name. +function firstNonTriviaIs(tokens: Token[], name: string): boolean { + for (const t of tokens) { + if (TRIVIA_TOKEN_NAMES.has(t.name)) continue + return t.name === name + } + return false +} + // True when ctx.t0 (the next token to be consumed) is one of the tokens // that unambiguously begin a new external declaration. Used by the // chomper to decide that a top-level `}` was the end of a function body. diff --git a/src/structure.ts b/src/structure.ts index 31e4a8f..ba28ddf 100644 --- a/src/structure.ts +++ b/src/structure.ts @@ -1009,14 +1009,196 @@ function parseAsmStatement(ts: TokenStream): CNode { } function takePreprocessorLine(ts: TokenStream): CNode { + return parseDirective(ts) || (() => { + // Defensive fallback — shouldn't be reached. + const startTkn = ts.peek()! + const node = makeNode('preprocessor_line', spanOf(startTkn)) + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PP_NEWLINE') { ts.takeInto(node); break } + ts.takeInto(node) + } + return node + })() +} + +// ---- Preprocessor directives --------------------------------------- + +// Discover the directive name (the first non-trivia token after the +// opening PP_HASH). Returns the lowercase src ('define', 'include', +// 'if', 'ifdef', 'ifndef', 'elif', 'else', 'endif', 'pragma', 'error', +// 'warning', 'line', 'undef', 'embed', 'include_next') or null. +function directiveName(ts: TokenStream, hashOff: number = 0): string | null { + const t = ts.peek(hashOff + 1) + if (!t) return null + return t.src +} + +export function parseDirective(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn || startTkn.name !== 'PP_HASH') return null + const dn = directiveName(ts) || '' + switch (dn) { + case 'define': return parseDefineDirective(ts) + case 'undef': return parseUndefDirective(ts) + case 'include': + case 'include_next': + case 'embed': return parseIncludeDirective(ts, dn) + case 'if': + case 'ifdef': + case 'ifndef': + case 'elif': + case 'elifdef': + case 'elifndef': + case 'else': + case 'endif': return parseConditionalDirective(ts, dn) + case 'pragma': return parseSimpleDirective(ts, 'pragma_directive') + case 'error': return parseSimpleDirective(ts, 'error_directive') + case 'warning': return parseSimpleDirective(ts, 'warning_directive') + case 'line': return parseSimpleDirective(ts, 'line_directive') + default: return parseSimpleDirective(ts, 'unknown_directive') + } +} + +function parseSimpleDirective(ts: TokenStream, kind: string): CNode { const startTkn = ts.peek()! - const node = makeNode('preprocessor_line', spanOf(startTkn)) + const node = makeNode(kind, spanOf(startTkn)) + ts.takeInto(node) // PP_HASH while (!ts.done()) { const n = ts.peekName() - if (n === 'PP_NEWLINE') { - ts.takeInto(node) - break + if (n === 'PP_NEWLINE') { ts.takeInto(node); break } + ts.takeInto(node) + } + return node +} + +// `#define ID` or `#define ID(params) body`. Function-like form requires +// no space between ID and `(`; we approximate this by checking that the +// `(` token immediately follows the macro-name token in the source. +export function parseDefineDirective(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('define_directive', spanOf(startTkn)) + ts.takeInto(node) // PP_HASH + // 'define' keyword token. + ts.takeInto(node) + + // Macro name. + const nameTkn = ts.peek() + if (nameTkn && (nameTkn.name === 'ID' || nameTkn.name === 'TYPEDEF_NAME' || + nameTkn.name === 'MACRO_NAME')) { + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.macroName = taken.tkn.src + + // Function-like? Check positional adjacency in source: `(` directly + // after the name (no whitespace). The matcher emits `#SP` for any + // gap which would have been buffered as trivia BEFORE the `(` if + // present — but we drop whitespace, so check token spans. + const lookahead = ts.peek() + if (lookahead && lookahead.name === 'PUNC_LPAREN' && + lookahead.sI === taken.tkn.sI + taken.tkn.len) { + node.macroKind = 'function-like' + const params = makeNode('macro_parameter_list', spanOf(lookahead)) + ts.takeInto(params) // '(' + node.macroParams = [] + while (!ts.done() && ts.peekName() !== 'PUNC_RPAREN') { + const t = ts.peek()! + if (t.name === 'PUNC_ELLIPSIS') { + node.macroVariadic = true + ts.takeInto(params) + } else if (t.name === 'PUNC_COMMA') { + ts.takeInto(params) + } else if (t.name === 'ID' || t.name === 'TYPEDEF_NAME') { + ts.takeInto(params) + node.macroParams.push(t.src) + } else { + ts.takeInto(params) // tolerant + } + } + if (ts.peekName() === 'PUNC_RPAREN') ts.takeInto(params) + node.children.push(params) + } else { + node.macroKind = 'object-like' } + } else { + node.macroKind = 'object-like' + } + + // Body: every remaining token until PP_NEWLINE. + const body = makeNode('macro_body', spanOf(ts.peek() || startTkn)) + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PP_NEWLINE') break + ts.takeInto(body) + } + node.children.push(body) + if (ts.peekName() === 'PP_NEWLINE') ts.takeInto(node) + return node +} + +export function parseUndefDirective(ts: TokenStream): CNode { + const startTkn = ts.peek()! + const node = makeNode('undef_directive', spanOf(startTkn)) + ts.takeInto(node) // PP_HASH + ts.takeInto(node) // 'undef' + const nameTkn = ts.peek() + if (nameTkn && (nameTkn.name === 'ID' || nameTkn.name === 'TYPEDEF_NAME' || + nameTkn.name === 'MACRO_NAME')) { + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.macroName = taken.tkn.src + } + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PP_NEWLINE') { ts.takeInto(node); break } + ts.takeInto(node) + } + return node +} + +export function parseIncludeDirective(ts: TokenStream, name: string): CNode { + const startTkn = ts.peek()! + const node = makeNode('include_directive', spanOf(startTkn)) + node.includeForm = name // 'include' | 'include_next' | 'embed' + ts.takeInto(node) // PP_HASH + ts.takeInto(node) // include keyword + + const next = ts.peek() + if (next) { + if (next.name === 'LIT_HEADER_NAME') { + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.headerName = taken.tkn.src + node.headerKind = taken.tkn.src.startsWith('<') ? 'angled' : 'quoted' + } else { + // Macro-form include: capture remaining tokens as a header_form node. + const hf = makeNode('header_form', spanOf(next)) + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PP_NEWLINE') break + ts.takeInto(hf) + } + node.children.push(hf) + } + } + + if (ts.peekName() === 'PP_NEWLINE') ts.takeInto(node) + return node +} + +export function parseConditionalDirective(ts: TokenStream, name: string): CNode { + const startTkn = ts.peek()! + const node = makeNode('conditional_directive', spanOf(startTkn)) + node.directive = name // 'if' | 'ifdef' | 'ifndef' | 'elif' | ... + ts.takeInto(node) // PP_HASH + ts.takeInto(node) // directive keyword + // Condition tokens until PP_NEWLINE (empty for #else / #endif). + while (!ts.done()) { + const n = ts.peekName() + if (n === 'PP_NEWLINE') { ts.takeInto(node); break } ts.takeInto(node) } return node @@ -1037,9 +1219,23 @@ export function structureExternalDeclaration(tokens: Token[]): { const ts = new TokenStream(tokens) if (ts.done()) return null - // Preprocessor lines start with PP_HASH and end with PP_NEWLINE; the - // preprocessor slice handles them later. For now just bail. - if (ts.peekName() === 'PP_HASH') return null + // Preprocessor lines: structure as a directive node and treat the + // whole external_declaration as that one directive. + if (ts.peekName() === 'PP_HASH') { + const dir = parseDirective(ts) + if (dir) { + // Drain any trailing tokens (shouldn't be any normally). + const out: Array = [dir] + while (!ts.done()) { + const taken = ts.take() + if (!taken) break + for (const tr of taken.trivia) out.push(tr) + out.push(taken.ref) + } + return { declKind: 'declaration', children: out } + } + return null + } // Specifiers (optional). const specs = parseDeclarationSpecifiers(ts) diff --git a/test/c.test.ts b/test/c.test.ts index afebf22..ab858bd 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -408,4 +408,72 @@ describe('c parser smoke', () => { assert.ok(findKind(out.children[0], 'do_statement')) }) + // ---- Preprocessor directives (slice 7) ------------------------------ + + test('preprocessor: #include with angled header name', () => { + const src = '#include \nint x;' + const out = j(src) + assert.equal(out.children.length, 2) + const inc = findKind(out.children[0], 'include_directive') + assert.ok(inc) + assert.equal(inc.headerKind, 'angled') + assert.equal(inc.headerName, '') + // Following declaration is unaffected. + assert.equal(out.children[1].declKind, 'declaration') + }) + + test('preprocessor: #include with quoted header name', () => { + const src = '#include "local.h"' + const out = j(src) + const inc = findKind(out.children[0], 'include_directive') + assert.equal(inc.headerKind, 'quoted') + assert.equal(inc.headerName, '"local.h"') + }) + + test('preprocessor: #define object-like', () => { + const src = '#define MAX 100\nint x = 1;' + const out = j(src) + const def = findKind(out.children[0], 'define_directive') + assert.equal(def.macroName, 'MAX') + assert.equal(def.macroKind, 'object-like') + assert.ok(findKind(def, 'macro_body')) + assert.equal(out.children[1].declKind, 'declaration') + }) + + test('preprocessor: #define function-like with params and variadic', () => { + const src = '#define LOG(fmt, ...) printf(fmt, __VA_ARGS__)\n' + const out = j(src) + const def = findKind(out.children[0], 'define_directive') + assert.equal(def.macroName, 'LOG') + assert.equal(def.macroKind, 'function-like') + assert.deepEqual(def.macroParams, ['fmt']) + assert.equal(def.macroVariadic, true) + }) + + test('preprocessor: #if / #endif each become directive nodes', () => { + const src = '#if FOO\nint x;\n#endif\n' + const out = j(src) + // Three external declarations: the #if line, the int x; line, the #endif. + assert.equal(out.children.length, 3) + const ifDir = findKind(out.children[0], 'conditional_directive') + assert.equal(ifDir.directive, 'if') + assert.equal(out.children[1].declKind, 'declaration') + const endDir = findKind(out.children[2], 'conditional_directive') + assert.equal(endDir.directive, 'endif') + }) + + test('preprocessor: #pragma / #error', () => { + const src = '#pragma once\n#error "boom"\n' + const out = j(src) + assert.ok(findKind(out.children[0], 'pragma_directive')) + assert.ok(findKind(out.children[1], 'error_directive')) + }) + + test('preprocessor: #undef', () => { + const src = '#define X 1\n#undef X\n' + const out = j(src) + assert.equal(findKind(out.children[0], 'define_directive').macroName, 'X') + assert.equal(findKind(out.children[1], 'undef_directive').macroName, 'X') + }) + }) From 32253a341d303fd7bdeb726a70341af07d5e9a22 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:11:53 +0000 Subject: [PATCH 08/25] Slice 8: parse function parameter lists into typed nodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit function_postfix nodes are no longer opaque '(' … ')' chunks. Each one now contains either: parameter_type_list parameter_declaration { declaredName? } declaration_specifiers declarator | abstract_declarator parameter_variadic (the '...' marker, also sets parameter_type_list.variadic = true) identifier_list (K&R-style identifier-only list) Special cases handled: - `()` — empty postfix, returned as-is - `(void)` — collapsed into a single parameter_declaration whose spec list contains the lone void - K&R `(a, b, c)` — detected by lookahead (every comma-separated item is exactly one ID, ending with ')') Abstract vs concrete declarator: parseParameterDeclaration tries the concrete form first; if no declaredName surfaces it backtracks and re-parses as abstract. This keeps `int qsort(void *, size_t, ...)` clean (no spurious declaredName on the size_t parameters) once size_t is registered as a typedef. Tests: void prototype, named ANSI parameters with declaredName extraction, variadic ellipsis, abstract parameters across a typedef boundary, and K&R-style identifier_list. --- src/structure.ts | 135 +++++++++++++++++++++++++++++++++++++++++++++-- test/c.test.ts | 64 ++++++++++++++++++++++ 2 files changed, 196 insertions(+), 3 deletions(-) diff --git a/src/structure.ts b/src/structure.ts index ba28ddf..f0bc4b7 100644 --- a/src/structure.ts +++ b/src/structure.ts @@ -611,9 +611,8 @@ function parseDirectDeclarator(ts: TokenStream, abstract: boolean): CNode | null continue } if (n === 'PUNC_LPAREN') { - const fn = makeNode('function_postfix', spanOf(ts.peek()!)) - consumeBalanced(ts, fn, 'PUNC_LPAREN', 'PUNC_RPAREN') - node.children.push(fn) + const fn = parseFunctionPostfix(ts) + if (fn) node.children.push(fn) continue } break @@ -623,6 +622,136 @@ function parseDirectDeclarator(ts: TokenStream, abstract: boolean): CNode | null return node } +// '(' parameter_type_list? ')' or '(' identifier_list? ')' (K&R) +export function parseFunctionPostfix(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn || startTkn.name !== 'PUNC_LPAREN') return null + const node = makeNode('function_postfix', spanOf(startTkn)) + ts.takeInto(node) // '(' + + // Empty list — `()` (K&R unspecified prototype). + if (ts.peekName() === 'PUNC_RPAREN') { + ts.takeInto(node) + return node + } + + // ANSI prototype with explicit `void` and no params. + if (ts.peekName() === 'KW_VOID' && ts.peekName(1) === 'PUNC_RPAREN') { + const ptl = makeNode('parameter_type_list', spanOf(ts.peek()!)) + const voidParam = makeNode('parameter_declaration', spanOf(ts.peek()!)) + const voidSpec = makeNode('declaration_specifiers', spanOf(ts.peek()!)) + voidParam.children.push(voidSpec) + ts.takeInto(voidSpec) // 'void' + ptl.children.push(voidParam) + node.children.push(ptl) + ts.takeInto(node) // ')' + return node + } + + // Detect K&R identifier list: every comma-separated item is a single + // ID with no specifier. Lookahead-only — falls back to ANSI parsing + // if the head doesn't match. + if (looksLikeKRIdentifierList(ts)) { + const list = makeNode('identifier_list', spanOf(ts.peek()!)) + while (!ts.done() && ts.peekName() !== 'PUNC_RPAREN') { + ts.takeInto(list) + } + node.children.push(list) + if (ts.peekName() === 'PUNC_RPAREN') ts.takeInto(node) + return node + } + + // ANSI parameter type list. + const ptl = makeNode('parameter_type_list', spanOf(ts.peek()!)) + while (!ts.done() && ts.peekName() !== 'PUNC_RPAREN') { + if (ts.peekName() === 'PUNC_ELLIPSIS') { + const ell = makeNode('parameter_variadic', spanOf(ts.peek()!)) + ts.takeInto(ell) + ptl.children.push(ell) + ptl.variadic = true + break + } + const p = parseParameterDeclaration(ts) + if (p) ptl.children.push(p) + else { + // Defensive: avoid infinite loop on tokens we don't recognise. + ts.takeInto(ptl) + } + if (ts.peekName() === 'PUNC_COMMA') ts.takeInto(ptl) + } + node.children.push(ptl) + if (ts.peekName() === 'PUNC_RPAREN') ts.takeInto(node) + return node +} + +function looksLikeKRIdentifierList(ts: TokenStream): boolean { + // The current position is the first token after `(`. K&R: every + // comma-separated item is exactly one ID and the closing ')' follows + // the last ID. + let i = 0 + let expectId = true + while (true) { + const t = ts.peek(i) + if (!t) return false + const n = t.name + if (expectId) { + if (n !== 'ID') return false + expectId = false + } else { + if (n === 'PUNC_RPAREN') return i > 0 + if (n === 'PUNC_COMMA') { expectId = true } else { return false } + } + i++ + if (i > 256) return false // safety + } +} + +// parameter_declaration: +// declaration_specifiers (declarator | abstract_declarator)? +export function parseParameterDeclaration(ts: TokenStream): CNode | null { + const startTkn = ts.peek() + if (!startTkn) return null + const node = makeNode('parameter_declaration', spanOf(startTkn)) + const specs = parseDeclarationSpecifiers(ts) + if (specs) node.children.push(specs) + + // Optional declarator. Decide concrete vs abstract: if the next + // non-trivia token is `,` or `)` (no declarator at all) we still emit + // an empty parameter (just the specs). Otherwise try a concrete + // declarator first, fall back to abstract. + const next = ts.peekName() + if (next === 'PUNC_COMMA' || next === 'PUNC_RPAREN' || next === null) { + return node.children.length > 0 ? node : null + } + + const m = ts.mark() + let d = parseDeclarator(ts, false) + if (!d || (!d.declaredName && !findKind(d, 'declaredName'))) { + // No identifier — fall back to abstract declarator. + ts.restore(m) + d = parseDeclarator(ts, true) + } + if (d) { + node.children.push(d) + if (d.declaredName) node.declaredName = d.declaredName + } + return node.children.length > 0 ? node : null +} + +// Tiny helper used above to detect whether a (possibly-abstract) +// declarator has any concrete name in it. Searches recursively. +function findKind(node: any, key: string): any { + if (!node) return null + if (node[key] !== undefined) return node + if (Array.isArray(node.children)) { + for (const c of node.children) { + const hit = findKind(c, key) + if (hit) return hit + } + } + return null +} + // ---- init-declarator-list ------------------------------------------- export function parseInitDeclaratorList(ts: TokenStream): CNode | null { diff --git a/test/c.test.ts b/test/c.test.ts index ab858bd..189ac10 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -476,4 +476,68 @@ describe('c parser smoke', () => { assert.equal(findKind(out.children[1], 'undef_directive').macroName, 'X') }) + // ---- Parameter lists (slice 8) -------------------------------------- + + test('parameters: void prototype', () => { + const src = 'int main(void);' + const out = j(src) + const fp = findKind(out.children[0], 'function_postfix') + assert.ok(fp) + const ptl = findKind(fp, 'parameter_type_list') + assert.ok(ptl) + const params = ptl.children.filter((c: any) => c.kind === 'parameter_declaration') + assert.equal(params.length, 1) + }) + + test('parameters: ANSI prototype with named parameters', () => { + const src = 'int add(int a, int b);' + const out = j(src) + const ptl = findKind(out.children[0], 'parameter_type_list') + const params = ptl.children.filter((c: any) => c.kind === 'parameter_declaration') + assert.equal(params.length, 2) + assert.deepEqual(params.map((p: any) => p.declaredName), ['a', 'b']) + }) + + test('parameters: variadic ellipsis', () => { + const src = 'int printf(const char *fmt, ...);' + const out = j(src) + const ptl = findKind(out.children[0], 'parameter_type_list') + assert.equal(ptl.variadic, true) + assert.ok(findKind(ptl, 'parameter_variadic')) + }) + + test('parameters: abstract declarators (after typedef registration)', () => { + // Pre-register size_t so the parser sees `size_t` as a TYPEDEF_NAME + // and treats it as a parameter type, not a parameter name. + const src = ` + typedef unsigned long size_t; + int qsort(void *, size_t, size_t, int (*)(const void *, const void *)); + ` + const out = j(src) + const decl = out.children.find((c: any) => findKind(c, 'function_postfix')) + assert.ok(decl, 'expected the qsort declaration') + const ptl = findKind(decl, 'parameter_type_list') + // Note: `int (*)(const void *, const void *)` is the *outer* + // parameter — its inner function_postfix has its own ptl, so we + // count by direct children only. + const params = ptl.children.filter((c: any) => c.kind === 'parameter_declaration') + assert.equal(params.length, 4) + // None of the four outer parameters should carry a declaredName. + for (const p of params) { + assert.equal(p.declaredName, undefined, + 'abstract parameter must not carry a declaredName') + } + }) + + test('parameters: identifier_list shape detected for K&R prototypes', () => { + // K&R declaration without body: `int f(a, b);` is a (very old) + // prototype without specifiers; the parser models it with an + // identifier_list inside the function_postfix. + const src = 'int f(a, b);' + const out = j(src) + const fp = findKind(out.children[0], 'function_postfix') + assert.ok(fp) + assert.ok(findKind(fp, 'identifier_list')) + }) + }) From 1835f13bb0f65bb2ce290340ad107364443de5d8 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:14:39 +0000 Subject: [PATCH 09/25] Slice 9: lex-time macro-name tagging via the macro table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Identifiers previously seen in a #define now lex as MACRO_NAME instead of ID, mirroring the typedef-name path. The grammar accepts MACRO_NAME wherever it accepts ID (added a small isIdLike helper and replaced the relevant call sites in structure.ts), so structuring is unchanged while clients can distinguish macro references from ordinary identifiers without consulting the macro table themselves. The identifier matcher consults ctx.meta.cmeta.macros after the typedef check. After a #define directive is structured into a define_directive node, registerMacrosFromTree calls reclassifyAsMacro which walks the lexer's pre-fetched lookahead (ctx.t and lex.pnt.token) mutating any matching ID tokens to MACRO_NAME — so the very first post-#define occurrence already carries the correct token name even when jsonic's lookahead got there first. #undef removes the entry from the macro table; subsequent uses of the name re-emerge as plain ID. Tests cover all three transitions. --- src/c.ts | 21 +++++++++++++++++++++ src/matchers.ts | 11 ++++++++--- src/structure.ts | 27 +++++++++++++++++---------- test/c.test.ts | 30 ++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 13 deletions(-) diff --git a/src/c.ts b/src/c.ts index b14ffde..c2739b9 100644 --- a/src/c.ts +++ b/src/c.ts @@ -646,6 +646,11 @@ function registerMacrosFromTree(node: any, ctx: Context): void { params: n.macroParams, variadic: !!n.macroVariadic, }) + // Reclassify any already-lexed lookahead tokens with this name + // from ID to MACRO_NAME. Subsequent macros are first picked up by + // the identifier matcher itself, but tokens fetched into ctx.t / + // pnt.token *before* this define ran need a manual fix-up. + reclassifyAsMacro(ctx, n.macroName) } else if (n.kind === 'undef_directive' && n.macroName) { cmeta.macros.undefine(n.macroName) } @@ -654,6 +659,22 @@ function registerMacrosFromTree(node: any, ctx: Context): void { visit(node) } +function reclassifyAsMacro(ctx: Context, name: string): void { + const lex = (ctx as any).lex + if (!lex) return + const idTin = (ctx.cfg as any).t['ID'] + const mnTin = (ctx.cfg as any).t['MACRO_NAME'] + const fix = (tkn: any) => { + if (!tkn || !tkn.isToken) return + if (tkn.tin === idTin && tkn.src === name) { + tkn.tin = mnTin + tkn.name = 'MACRO_NAME' + } + } + if (Array.isArray(ctx.t)) for (const tkn of ctx.t) fix(tkn) + if (lex.pnt && Array.isArray(lex.pnt.token)) for (const tkn of lex.pnt.token) fix(tkn) +} + // True iff the first non-trivia entry in `tokens` has the given name. function firstNonTriviaIs(tokens: Token[], name: string): boolean { for (const t of tokens) { diff --git a/src/matchers.ts b/src/matchers.ts index 75d56f7..7cb36ab 100644 --- a/src/matchers.ts +++ b/src/matchers.ts @@ -300,9 +300,14 @@ export function makeIdentifierMatcher() { return emit(lex, 'TYPEDEF_NAME', word, word, word.length) } - // Macro-name tagging is informational; we still emit ID so the grammar - // treats it like any other identifier. Downstream rule actions can - // consult ctx.meta.cmeta.macros to set call_expr.isMacro. + // Macro-name tagging: identifiers previously seen in a #define + // surface as MACRO_NAME so call sites can be distinguished from + // ordinary function calls. The grammar accepts MACRO_NAME wherever + // it accepts ID. + if (!meta.mode.inDirective && meta.macros.has(word)) { + return emit(lex, 'MACRO_NAME', word, word, word.length) + } + return emit(lex, 'ID', word, word, word.length) } } diff --git a/src/structure.ts b/src/structure.ts index f0bc4b7..38333ab 100644 --- a/src/structure.ts +++ b/src/structure.ts @@ -72,6 +72,13 @@ const ATTRIBUTE_OPENERS = new Set([ 'KW___DECLSPEC', ]) +// True for identifier-like tokens (plain IDs and macro-name IDs that +// the lexer flagged via the macro table). TYPEDEF_NAME is NOT included +// here — it's treated specially by callers when relevant. +function isIdLike(name: string | null): boolean { + return name === 'ID' || name === 'MACRO_NAME' +} + function isSpecifierStart(name: string): boolean { return STORAGE_CLASS.has(name) || TYPE_QUALIFIER.has(name) || @@ -275,7 +282,7 @@ export function parseStructOrUnionSpec(ts: TokenStream): CNode | null { // Optional tag identifier. const next = ts.peek() - if (next && (next.name === 'ID' || next.name === 'TYPEDEF_NAME')) { + if (next && (isIdLike(next.name) || next.name === 'TYPEDEF_NAME')) { const taken = ts.take()! for (const tr of taken.trivia) node.children.push(tr) node.children.push(taken.ref) @@ -431,7 +438,7 @@ export function parseEnumSpec(ts: TokenStream): CNode | null { } const next = ts.peek() - if (next && (next.name === 'ID' || next.name === 'TYPEDEF_NAME')) { + if (next && (isIdLike(next.name) || next.name === 'TYPEDEF_NAME')) { const taken = ts.take()! for (const tr of taken.trivia) node.children.push(tr) node.children.push(taken.ref) @@ -568,7 +575,7 @@ function parseDirectDeclarator(ts: TokenStream, abstract: boolean): CNode | null // Primary: ID, or '(' declarator ')', or empty (abstract). const n0 = ts.peekName() - if (n0 === 'ID') { + if (isIdLike(n0)) { const taken = ts.take()! for (const tr of taken.trivia) node.children.push(tr) node.children.push(taken.ref) @@ -582,7 +589,7 @@ function parseDirectDeclarator(ts: TokenStream, abstract: boolean): CNode | null const inner = ts.peek() if (inner && (inner.name === 'PUNC_STAR' || inner.name === 'PUNC_LPAREN' || - inner.name === 'ID' || + isIdLike(inner.name) || ATTRIBUTE_OPENERS.has(inner.name))) { // Subdeclarator const sub = parseDeclarator(ts, abstract) @@ -695,7 +702,7 @@ function looksLikeKRIdentifierList(ts: TokenStream): boolean { if (!t) return false const n = t.name if (expectId) { - if (n !== 'ID') return false + if (!isIdLike(n)) return false expectId = false } else { if (n === 'PUNC_RPAREN') return i > 0 @@ -946,7 +953,7 @@ export function parseStatement(ts: TokenStream): CNode | null { // ID ':' starts a labeled statement; otherwise it's an expression // statement. - if (n0 === 'ID' && ts.peekName(1) === 'PUNC_COLON') { + if (isIdLike(n0) && ts.peekName(1) === 'PUNC_COLON') { return parseLabeledStatement(ts) } @@ -1213,7 +1220,7 @@ export function parseDefineDirective(ts: TokenStream): CNode { // Macro name. const nameTkn = ts.peek() - if (nameTkn && (nameTkn.name === 'ID' || nameTkn.name === 'TYPEDEF_NAME' || + if (nameTkn && (isIdLike(nameTkn.name) || nameTkn.name === 'TYPEDEF_NAME' || nameTkn.name === 'MACRO_NAME')) { const taken = ts.take()! for (const tr of taken.trivia) node.children.push(tr) @@ -1238,7 +1245,7 @@ export function parseDefineDirective(ts: TokenStream): CNode { ts.takeInto(params) } else if (t.name === 'PUNC_COMMA') { ts.takeInto(params) - } else if (t.name === 'ID' || t.name === 'TYPEDEF_NAME') { + } else if (isIdLike(t.name) || t.name === 'TYPEDEF_NAME') { ts.takeInto(params) node.macroParams.push(t.src) } else { @@ -1272,7 +1279,7 @@ export function parseUndefDirective(ts: TokenStream): CNode { ts.takeInto(node) // PP_HASH ts.takeInto(node) // 'undef' const nameTkn = ts.peek() - if (nameTkn && (nameTkn.name === 'ID' || nameTkn.name === 'TYPEDEF_NAME' || + if (nameTkn && (isIdLike(nameTkn.name) || nameTkn.name === 'TYPEDEF_NAME' || nameTkn.name === 'MACRO_NAME')) { const taken = ts.take()! for (const tr of taken.trivia) node.children.push(tr) @@ -1370,7 +1377,7 @@ export function structureExternalDeclaration(tokens: Token[]): { const specs = parseDeclarationSpecifiers(ts) // If no specifiers AND no declarator follows (e.g. just `;`), bail. - if (!specs && ts.peekName() !== 'ID' && ts.peekName() !== 'PUNC_STAR' && + if (!specs && !isIdLike(ts.peekName()) && ts.peekName() !== 'PUNC_STAR' && ts.peekName() !== 'PUNC_LPAREN') { return null } diff --git a/test/c.test.ts b/test/c.test.ts index 189ac10..fff2907 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -540,4 +540,34 @@ describe('c parser smoke', () => { assert.ok(findKind(fp, 'identifier_list')) }) + // ---- Macro-name tagging (slice 9) ----------------------------------- + + test('macro tagging: identifier in #define body becomes MACRO_NAME later', () => { + const src = '#define MAX 100\nint x = MAX;' + const out = j(src) + // The second declaration's `MAX` token must lex as MACRO_NAME. + const decl = out.children[1] + const maxTok = findTokenBySrc(decl, 'MAX') + assert.equal(maxTok?.tname, 'MACRO_NAME') + // And `x` is still ID. + assert.equal(findTokenBySrc(decl, 'x')?.tname, 'ID') + }) + + test('macro tagging: function-like macro reference in expression', () => { + const src = '#define INC(x) ((x)+1)\nint y = INC(5);' + const out = j(src) + const decl = out.children[1] + const incTok = findTokenBySrc(decl, 'INC') + assert.equal(incTok?.tname, 'MACRO_NAME') + }) + + test('macro tagging: undef removes the macro name', () => { + const src = '#define X 1\nint a = X;\n#undef X\nint b = X;' + const out = j(src) + // Before undef, X is MACRO_NAME. + assert.equal(findTokenBySrc(out.children[1], 'X')?.tname, 'MACRO_NAME') + // After undef, X is back to plain ID. + assert.equal(findTokenBySrc(out.children[3], 'X')?.tname, 'ID') + }) + }) From 6d184e9a4eb02535f60e6a080b186e8e2cf0fc78 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:16:39 +0000 Subject: [PATCH 10/25] Slice 10: structure call expressions with isMacro tagging Inside expression_statement, initializer, and jump_statement bodies, the post-chomp pass now promotes ID/MACRO_NAME-followed-by-(args) sequences into nested call_expression nodes. The grammar context for calls is identical regardless of statement form, so a single structureCallsInPlace helper handles all three. call_expression { callee, isMacro } argument_list '(' ')' isMacro is set from the callee token's tname (true for MACRO_NAME), giving consumers a syntactic flag that distinguishes a macro invocation from a real function call without re-querying the macro table. Recursion is handled by structuring the argument list's interior as a synthetic node and inlining the result, so g(f(1), h(2)) produces three nested call_expression nodes. Tests: simple call (isMacro false), macro invocation (isMacro true), nested calls inside arguments. --- src/structure.ts | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ test/c.test.ts | 41 ++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/src/structure.ts b/src/structure.ts index 38333ab..5bfcf15 100644 --- a/src/structure.ts +++ b/src/structure.ts @@ -817,6 +817,87 @@ export function parseInitDeclarator(ts: TokenStream): CNode | null { return node } +// Promote `ID(args)` and `MACRO_NAME(args)` patterns inside `node`'s +// flat children list into nested call_expression nodes. Recurses into +// any non-token children. The grammatical context is "anywhere an +// expression can appear" — call sites have the same shape regardless +// of the surrounding statement form. +// +// Sets isMacro: true on calls whose callee token was MACRO_NAME. +function structureCallsInPlace(node: CNode): void { + if (!Array.isArray(node.children)) return + const ch = node.children + const out: Array = [] + let i = 0 + while (i < ch.length) { + const c = ch[i] as any + // Recurse into existing nested nodes first. + if (c.kind !== 'token') { + structureCallsInPlace(c) + out.push(c) + i++ + continue + } + // Identifier-ish callee token followed by '(' (skipping trivia)? + if ((c.tname === 'ID' || c.tname === 'MACRO_NAME')) { + let j = i + 1 + // skip trivia between callee and '(' + while (j < ch.length && (ch[j] as any).kind === 'token' && + PRESERVED_TRIVIA.has((ch[j] as any).tname)) j++ + if (j < ch.length && (ch[j] as any).kind === 'token' && + (ch[j] as any).tname === 'PUNC_LPAREN') { + // Find matching ')' in flat children. + let depth = 1 + let k = j + 1 + while (k < ch.length && depth > 0) { + const cl = ch[k] as any + if (cl.kind === 'token') { + if (cl.tname === 'PUNC_LPAREN') depth++ + else if (cl.tname === 'PUNC_RPAREN') { + depth-- + if (depth === 0) break + } + } + k++ + } + if (depth === 0) { + const callNode = makeNode('call_expression', c.span) + callNode.callee = c.src + callNode.isMacro = c.tname === 'MACRO_NAME' + // The callee token + any leading trivia after it (between + // callee and `(`). + callNode.children.push(c) + for (let m = i + 1; m < j; m++) callNode.children.push(ch[m]) + // Argument-list node carrying `(` … `)` plus structured + // sub-call recursion. + const argList = makeNode('argument_list', (ch[j] as any).span) + argList.children.push(ch[j]) // '(' + // Slice out the inner tokens, recurse on a synthetic node to + // structure nested calls, then flatten back. + const inner: any[] = [] + for (let m = j + 1; m < k; m++) inner.push(ch[m]) + const innerNode: CNode = { + kind: '__inner__', + span: argList.span, + children: inner, + trivia: { leading: [], trailing: [] }, + } + structureCallsInPlace(innerNode) + for (const ic of innerNode.children) argList.children.push(ic) + argList.children.push(ch[k]) // ')' + callNode.children.push(argList) + out.push(callNode) + i = k + 1 + continue + } + } + } + out.push(c) + i++ + } + node.children = out +} + // Initializer is opaque-balanced for now: a single token, or a brace // group, or anything until a top-level `,` or `;` or `}`. export function parseInitializer(ts: TokenStream): CNode | null { @@ -845,6 +926,7 @@ export function parseInitializer(ts: TokenStream): CNode | null { (n === 'PUNC_COMMA' || n === 'PUNC_SEMI' || n === 'PUNC_RBRACE')) break ts.takeInto(node) } + structureCallsInPlace(node) return node } @@ -1055,6 +1137,7 @@ function parseJumpStatement(ts: TokenStream): CNode { ts.takeInto(node) } if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(node) + structureCallsInPlace(node) return node } @@ -1119,6 +1202,11 @@ function parseExpressionStatement(ts: TokenStream): CNode { ts.takeInto(node) } if (ts.peekName() === 'PUNC_SEMI') ts.takeInto(node) + // Promote any ID/MACRO_NAME-followed-by-(…) shapes to call_expression + // sub-nodes. Tags isMacro = true when the callee was MACRO_NAME so + // consumers can distinguish a macro invocation from a real function + // call without consulting the macro table. + structureCallsInPlace(node) return node } diff --git a/test/c.test.ts b/test/c.test.ts index fff2907..fa0616d 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -570,4 +570,45 @@ describe('c parser smoke', () => { assert.equal(findTokenBySrc(out.children[3], 'X')?.tname, 'ID') }) + // ---- Call-expression structuring (slice 10) ------------------------- + + test('calls: simple function call wraps as call_expression', () => { + const src = 'void g(void) { f(1, 2); }' + const out = j(src) + const expr = findKind(out.children[0], 'expression_statement') + const call = findKind(expr, 'call_expression') + assert.ok(call) + assert.equal(call.callee, 'f') + assert.equal(call.isMacro, false) + assert.ok(findKind(call, 'argument_list')) + }) + + test('calls: macro invocation tagged isMacro', () => { + const src = '#define INC(x) ((x)+1)\nvoid g(void) { int y = INC(5); }' + const out = j(src) + // The macro invocation lives inside an init_declarator's initializer. + const init = findKind(out.children[1], 'initializer') + const call = findKind(init, 'call_expression') + assert.ok(call) + assert.equal(call.callee, 'INC') + assert.equal(call.isMacro, true) + }) + + test('calls: nested function call recursively structured', () => { + const src = 'void g(void) { return f(g(1), h(2)); }' + const out = j(src) + const ret = findKind(out.children[0], 'jump_statement') + const outerCall = findKind(ret, 'call_expression') + assert.equal(outerCall.callee, 'f') + // Two nested call_expressions inside outerCall. + const inner: any[] = [] + const visit = (n: any) => { + if (!n) return + if (n.kind === 'call_expression' && n !== outerCall) inner.push(n) + if (Array.isArray(n.children)) for (const c of n.children) visit(c) + } + visit(outerCall) + assert.deepEqual(inner.map((c) => c.callee).sort(), ['g', 'h']) + }) + }) From e258cac70f22890882e07caf778a03877ac556e6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:19:23 +0000 Subject: [PATCH 11/25] Slice 11: nest preprocessor conditional groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a translation_unit-level post-pass that folds the flat sequence of #if/#ifdef/#ifndef … (#elif…)* (#else)? … #endif directives into a single conditional_group node containing typed branches. Best-effort: unmatched #endif or unterminated #if leaves the surrounding flat sequence untouched so the rest of the tree stays intact. Output shape: conditional_group branches: [ conditional_branch { branchKind: 'if'|'ifdef'|'ifndef'|'elif'|'elifdef'|'elifndef'|'else', directive: , body: [...], children: [directive, ...body] // depth-first walk fidelity }, ... ] endif: children: [...branches, endif] Nested #if … #endif inside a branch are recursively grouped by re-running structureConditionalGroups on the branch body. The pass also re-runs inside any preserved children (e.g. function bodies) so preprocessor groups that live mid-function get the same treatment. Tests: simple if/endif fold, three-way if/elif/else, nested ifdef inside an outer ifdef, and best-effort handling of a stray #endif (left flat). --- src/c.ts | 7 ++- src/structure.ts | 129 +++++++++++++++++++++++++++++++++++++++++++++++ test/c.test.ts | 84 +++++++++++++++++++++++++++--- 3 files changed, 211 insertions(+), 9 deletions(-) diff --git a/src/c.ts b/src/c.ts index c2739b9..a2087ff 100644 --- a/src/c.ts +++ b/src/c.ts @@ -31,7 +31,7 @@ import { PUNCTUATORS, keywordTokenName, } from './tokens.js' -import { structureExternalDeclaration } from './structure.js' +import { structureExternalDeclaration, structureConditionalGroups } from './structure.js' export interface COptions { // Reserved for future flags (strict mode, dialect selection, etc.) @@ -188,6 +188,11 @@ const C: any = function C(jsonic: Jsonic, _options: COptions): void { { s: ['#ZZ'], b: 1, g: 'tu-empty' }, { p: 'extdecl_loop', g: 'tu-loop' }, ]) + .bc((rule: Rule) => { + // After all external_declarations have accumulated, fold + // #if … #endif sequences into conditional_group nodes. + structureConditionalGroups(rule.node) + }) .close([ { s: ['#ZZ'], g: 'tu-end' }, ]) diff --git a/src/structure.ts b/src/structure.ts index 5bfcf15..3ea5e68 100644 --- a/src/structure.ts +++ b/src/structure.ts @@ -1428,6 +1428,135 @@ export function parseConditionalDirective(ts: TokenStream, name: string): CNode return node } +// ---- Conditional-group nesting ------------------------------------- + +// Walk a translation_unit's flat children list and collapse contiguous +// runs of `#if`/`#ifdef`/`#ifndef` … `#elif`/`#else` … `#endif` into a +// single conditional_group node containing branches. Best-effort: an +// unmatched #endif or an unterminated #if leaves the surrounding +// children unchanged so the rest of the tree stays intact. +// +// Output shape: +// conditional_group +// branches: [ +// { kind: 'conditional_branch', branchKind: 'if'|'ifdef'|'ifndef'| +// 'elif'|'elifdef'| +// 'elifndef'|'else', +// children: [, ] } +// ... +// ] +// endif: +export function structureConditionalGroups(parent: CNode): void { + if (!Array.isArray(parent.children)) return + const ch = parent.children + const out: any[] = [] + let i = 0 + while (i < ch.length) { + const c = ch[i] as any + const dir = leadingConditionalDirective(c) + if (dir && /^(if|ifdef|ifndef)$/.test(dir.directive)) { + const consumed = tryBuildConditionalGroup(ch, i) + if (consumed) { + out.push(consumed.node) + i = consumed.next + continue + } + } + out.push(c) + i++ + } + parent.children = out + // Recurse into preserved children (e.g. function bodies). + for (const c of out) { + if (c && c.kind && Array.isArray(c.children)) { + structureConditionalGroups(c) + } + } +} + +// Return the conditional_directive node embedded as the first child of +// an external_declaration, if any. +function leadingConditionalDirective(node: any): any | null { + if (!node || node.kind !== 'external_declaration') return null + const first = (node.children || []).find( + (c: any) => c && c.kind === 'conditional_directive', + ) + return first || null +} + +// Attempt to build a conditional_group starting at index `from`. Returns +// the new node and the index after the closing #endif, or null if no +// matching #endif was found at the same nesting level. +function tryBuildConditionalGroup( + children: any[], from: number, +): { node: CNode; next: number } | null { + // First pass: scan ahead with a depth counter to find the matching + // #endif. If none, bail. + let depth = 0 + let endIdx = -1 + for (let i = from; i < children.length; i++) { + const dir = leadingConditionalDirective(children[i]) + if (!dir) continue + if (/^(if|ifdef|ifndef)$/.test(dir.directive)) depth++ + else if (dir.directive === 'endif') { + depth-- + if (depth === 0) { endIdx = i; break } + } + } + if (endIdx < 0) return null + + // Second pass: split [from … endIdx-1] into branches at top-level + // #elif/#else. + const startCh = children[from] as CNode + const groupNode = makeNode('conditional_group', startCh.span) + groupNode.branches = [] as any[] + let branchStart = from + let innerDepth = 0 + for (let i = from + 1; i < endIdx; i++) { + const dir = leadingConditionalDirective(children[i]) + if (!dir) continue + if (/^(if|ifdef|ifndef)$/.test(dir.directive)) innerDepth++ + else if (dir.directive === 'endif') innerDepth-- + else if (innerDepth === 0 && + /^(elif|elifdef|elifndef|else)$/.test(dir.directive)) { + pushBranch(groupNode, children, branchStart, i) + branchStart = i + } + } + pushBranch(groupNode, children, branchStart, endIdx) + + // Endif as a separate field (the directive itself, for full fidelity). + groupNode.endif = children[endIdx] + // Also append it to children so a depth-first walk still emits the + // raw tokens in order. + groupNode.children.push(...groupNode.branches) + groupNode.children.push(children[endIdx]) + + return { node: groupNode, next: endIdx + 1 } +} + +function pushBranch(group: CNode, children: any[], from: number, to: number): void { + const head = children[from] + const dir = leadingConditionalDirective(head) + const branch = makeNode('conditional_branch', head.span) + branch.branchKind = dir ? dir.directive : 'unknown' + // The directive itself is preserved on a side field; the branch's + // `children` list holds just the body items so consumers can iterate + // them without filtering. + branch.directive = head + // Recurse into body so nested #if … #endif inside a branch also get + // grouped. + const inner = makeNode('__branch_body__', head.span) + for (let k = from + 1; k < to; k++) inner.children.push(children[k]) + structureConditionalGroups(inner) + // Final children: the directive followed by the (possibly grouped) + // body, so a depth-first walk still yields original tokens. + branch.children = [head, ...inner.children] + // Body-only view for consumers. + branch.body = inner.children + group.branches.push(branch) +} + // ---- top-level dispatch --------------------------------------------- // Parse a single external_declaration from the token list. Returns the diff --git a/test/c.test.ts b/test/c.test.ts index fa0616d..267978b 100644 --- a/test/c.test.ts +++ b/test/c.test.ts @@ -450,16 +450,19 @@ describe('c parser smoke', () => { assert.equal(def.macroVariadic, true) }) - test('preprocessor: #if / #endif each become directive nodes', () => { + test('preprocessor: #if … #endif fold into a conditional_group', () => { const src = '#if FOO\nint x;\n#endif\n' const out = j(src) - // Three external declarations: the #if line, the int x; line, the #endif. - assert.equal(out.children.length, 3) - const ifDir = findKind(out.children[0], 'conditional_directive') - assert.equal(ifDir.directive, 'if') - assert.equal(out.children[1].declKind, 'declaration') - const endDir = findKind(out.children[2], 'conditional_directive') - assert.equal(endDir.directive, 'endif') + assert.equal(out.children.length, 1) + const grp = out.children[0] + assert.equal(grp.kind, 'conditional_group') + assert.equal(grp.branches.length, 1) + const b = grp.branches[0] + assert.equal(b.branchKind, 'if') + // The branch's body view contains exactly the body declaration. + assert.equal(b.body.length, 1) + assert.equal(b.body[0].kind, 'external_declaration') + assert.ok(grp.endif) }) test('preprocessor: #pragma / #error', () => { @@ -611,4 +614,69 @@ describe('c parser smoke', () => { assert.deepEqual(inner.map((c) => c.callee).sort(), ['g', 'h']) }) + // ---- Conditional groups (slice 11) ---------------------------------- + + test('conditional_group: if/elif/else/endif with three branches', () => { + const src = ` + #if FOO + int a; + #elif BAR + int b; + #else + int c; + #endif + ` + const out = j(src) + assert.equal(out.children.length, 1) + const grp = out.children[0] + assert.equal(grp.kind, 'conditional_group') + assert.deepEqual( + grp.branches.map((b: any) => b.branchKind), + ['if', 'elif', 'else'], + ) + // Each branch's body has exactly one external declaration. + assert.deepEqual( + grp.branches.map((b: any) => b.body.length), + [1, 1, 1], + ) + }) + + test('conditional_group: nested #if inside a branch', () => { + const src = ` + #ifdef OUTER + int a; + #ifdef INNER + int b; + #endif + int c; + #endif + ` + const out = j(src) + const outer = out.children[0] + assert.equal(outer.kind, 'conditional_group') + const inner = outer.branches[0].body.find( + (c: any) => c.kind === 'conditional_group', + ) + assert.ok(inner, 'expected nested conditional_group') + assert.deepEqual( + inner.branches.map((b: any) => b.branchKind), + ['ifdef'], + ) + }) + + test('conditional_group: best-effort leaves stray #endif flat', () => { + const src = ` + int x; + #endif + int y; + ` + const out = j(src) + // No matching #if, so the #endif stays as its own external_declaration. + const kinds = out.children.map((c: any) => { + const dir = c.children?.find((x: any) => x.kind === 'conditional_directive') + return dir ? `dir:${dir.directive}` : c.declKind + }) + assert.deepEqual(kinds, ['declaration', 'dir:endif', 'declaration']) + }) + }) From 2a454a1e21e0e1f31133b0c8004de699799e4798 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Apr 2026 14:23:07 +0000 Subject: [PATCH 12/25] Slice 12: structured C expression parsing (Pratt + precedence) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add src/expr.ts: a hand-rolled Pratt-style parser covering the full C operator-precedence table from C23 §6.5. All expression contexts — expression_statement bodies, jump_statement (return/goto) operands, init_declarator initializers — now flow through it instead of being absorbed as flat tokens with a post-pass. Output shapes (all preserve every source token via depth-first children): literal_expression { literalKind, value } identifier_expression { name } paren_expression call_expression { callee, isMacro, argument_list } subscript_expression { target, index_list } member_expression { object, op ('.'|'->'), memberName } postfix_unary_expression { target, op ('++'|'--') } unary_expression { op, operand } // ++/--/+/-/!/~/*/&/sizeof/_Alignof/... cast_expression { typeName, operand } binary_expression { op, left, right } // 11 precedence levels conditional_expression { cond, then, else } assignment_expression { left, op, right } // right-assoc comma_expression generic_selection statement_expression // GCC ({ ... }) compound_literal { typeName, initializer_list } Implementation notes: - Cast vs paren-expression vs compound-literal disambiguation peeks one token past `(`. Type-name detection accepts type keywords and TYPEDEF_NAMEs (the typedef-name table is already populated by the earlier slices). - sizeof / _Alignof on a parenthesised type-name produce a type_name operand; on an expression they recurse into parseUnary. - Adjacent string literals are folded into a single literal_expression. - Macro-call detection moves into parsePostfix's call branch: when the immediate target is an identifier_expression whose token was MACRO_NAME, isMacro=true. The slice-10 post-pass is no longer needed for these contexts and was removed. Tests: precedence 1+2*3, right-assoc assignment chain, ternary, postfix subscript+member chain, prefix -/!/* unary, typedef-name cast, sizeof on expr and on type-name, adjacent-string concatenation. --- src/expr.ts | 492 +++++++++++++++++++++++++++++++++++++++++++++++ src/structure.ts | 73 ++----- test/c.test.ts | 103 ++++++++++ 3 files changed, 615 insertions(+), 53 deletions(-) create mode 100644 src/expr.ts diff --git a/src/expr.ts b/src/expr.ts new file mode 100644 index 0000000..b90245e --- /dev/null +++ b/src/expr.ts @@ -0,0 +1,492 @@ +/* Copyright (c) 2026 Richard Rodger and contributors, MIT License */ + +// Hand-rolled Pratt-style parser for C expressions, with the full +// operator-precedence table from C23 §6.5. Used by structure.ts in +// every expression context (expression_statement bodies, initializer +// values, jump-statement return values, condition headers). +// +// Output: a tree of nodes whose leaves are token-refs and whose +// branches are kind-tagged shapes. Walking depth-first still yields +// the original token sequence, so source fidelity is preserved. +// +// What's covered: +// - literal, identifier, parenthesised, generic_selection, sizeof, +// _Alignof, statement-expression `({ ... })` (GCC), compound +// literal `(type){ ... }` +// - postfix: call_expression, subscript_expression, +// member_expression, postfix_unary_expression +// - prefix: unary_expression (++ -- + - ! ~ * & sizeof _Alignof +// __real__ __imag__) +// - cast: cast_expression `( type-name ) operand` — only when +// the parenthesised head is unambiguously a type-name +// (typedef-name or simple type keyword). +// - binary: 11 levels (multiplicative through logical-or) +// - ternary: conditional_expression (right-assoc) +// - assignment: assignment_expression (right-assoc, all =/+=/-=/...) +// - comma: comma_expression +// +// Missing (left for future slices): +// - GCC type compound expressions like `__builtin_choose_expr(...)` +// beyond plain identifier-call recognition (they parse as ordinary +// calls today). + +import type { Token } from 'jsonic' +import type { TokenStream, CNode, CTokenRef } from './structure.js' + +// We intentionally re-import the helpers we need rather than coupling +// structure.ts to expr.ts in both directions. +import { } from './structure.js' + +const PRESERVED_TRIVIA = new Set([ + 'TRIVIA_LINE_COMMENT', 'TRIVIA_BLOCK_COMMENT', 'TRIVIA_LINE_CONT', +]) + +const TYPE_KEYWORDS = new Set([ + 'KW_VOID', 'KW_CHAR', 'KW_SHORT', 'KW_INT', 'KW_LONG', 'KW_FLOAT', + 'KW_DOUBLE', 'KW_SIGNED', 'KW_UNSIGNED', 'KW_BOOL', 'KW__BOOL', + 'KW__COMPLEX', 'KW__IMAGINARY', + 'KW___SIGNED__', 'KW___SIGNED', + 'KW___INT8', 'KW___INT16', 'KW___INT32', 'KW___INT64', + 'KW_CONST', 'KW_VOLATILE', 'KW_RESTRICT', 'KW__ATOMIC', + 'KW___CONST__', 'KW___CONST', + 'KW___VOLATILE__', 'KW___VOLATILE', + 'KW___RESTRICT__', 'KW___RESTRICT', + 'KW_STRUCT', 'KW_UNION', 'KW_ENUM', + 'KW_TYPEOF', 'KW_TYPEOF_UNQUAL', + 'KW___TYPEOF__', 'KW___TYPEOF', + 'KW__BITINT', +]) + +function makeNode(kind: string, span: any): CNode { + return { kind, span, children: [], trivia: { leading: [], trailing: [] } } as CNode +} + +function tokenRef(t: Token): CTokenRef { + return { + kind: 'token', tname: t.name, src: t.src, + span: { start: t.sI, end: t.sI + t.len, line: t.rI, col: t.cI }, + } +} + +function spanOf(t: Token) { + return { start: t.sI, end: t.sI + t.len, line: t.rI, col: t.cI } +} + +// Push the next real token with leading trivia onto `node`. Returns the +// underlying Token or null at end-of-stream. +function takeTokenInto(ts: TokenStream, node: CNode): Token | null { + return ts.takeInto(node) +} + +// ---- Operator tables ------------------------------------------------ + +interface BinaryOp { name: string; prec: number; rightAssoc?: boolean } + +// Precedence levels — higher number binds tighter. +// 16: unary / postfix (handled separately) +// 13: multiplicative * / % +// 12: additive + - +// 11: shift << >> +// 10: relational < <= > >= +// 9: equality == != +// 8: bitand & +// 7: bitxor ^ +// 6: bitor | +// 5: logical-and && +// 4: logical-or || +// 3: ternary (handled separately as a post-step) +// 2: assignment (right-assoc, handled separately) +// 1: comma (handled separately at the top) +const BINARY_OPS: Record = { + PUNC_STAR: { name: '*', prec: 13 }, + PUNC_SLASH: { name: '/', prec: 13 }, + PUNC_PERCENT: { name: '%', prec: 13 }, + PUNC_PLUS: { name: '+', prec: 12 }, + PUNC_MINUS: { name: '-', prec: 12 }, + PUNC_LSHIFT: { name: '<<', prec: 11 }, + PUNC_RSHIFT: { name: '>>', prec: 11 }, + PUNC_LT: { name: '<', prec: 10 }, + PUNC_LE: { name: '<=', prec: 10 }, + PUNC_GT: { name: '>', prec: 10 }, + PUNC_GE: { name: '>=', prec: 10 }, + PUNC_EQ: { name: '==', prec: 9 }, + PUNC_NE: { name: '!=', prec: 9 }, + PUNC_AMP: { name: '&', prec: 8 }, + PUNC_CARET: { name: '^', prec: 7 }, + PUNC_PIPE: { name: '|', prec: 6 }, + PUNC_AND_AND: { name: '&&', prec: 5 }, + PUNC_OR_OR: { name: '||', prec: 4 }, +} + +const ASSIGN_OPS = new Set([ + 'PUNC_ASSIGN', 'PUNC_PLUS_ASSIGN', 'PUNC_MINUS_ASSIGN', + 'PUNC_STAR_ASSIGN', 'PUNC_SLASH_ASSIGN', 'PUNC_PERCENT_ASSIGN', + 'PUNC_LSHIFT_ASSIGN', 'PUNC_RSHIFT_ASSIGN', + 'PUNC_AMP_ASSIGN', 'PUNC_CARET_ASSIGN', 'PUNC_PIPE_ASSIGN', +]) + +const PREFIX_OPS = new Set([ + 'PUNC_PLUS_PLUS', 'PUNC_MINUS_MINUS', + 'PUNC_PLUS', 'PUNC_MINUS', 'PUNC_BANG', 'PUNC_TILDE', + 'PUNC_STAR', 'PUNC_AMP', + 'KW_SIZEOF', 'KW__ALIGNOF', 'KW_ALIGNOF', 'KW___ALIGNOF__', 'KW___ALIGNOF', + 'KW___REAL__', 'KW___IMAG__', 'KW___EXTENSION__', +]) + +const POSTFIX_OPS = new Set(['PUNC_PLUS_PLUS', 'PUNC_MINUS_MINUS']) + +// ---- Stoppers helpers ---------------------------------------------- + +function isStop(name: string | null, stoppers: Set): boolean { + return name === null || stoppers.has(name) +} + +// ---- Entry --------------------------------------------------------- + +export function parseExpression( + ts: TokenStream, stoppers: Set, +): CNode | null { + return parseComma(ts, stoppers) +} + +// Comma: lowest precedence. Right-assoc isn't needed semantically; +// model as a left-grown list so consumers see operands in source order. +function parseComma(ts: TokenStream, stoppers: Set): CNode | null { + let first = parseAssignment(ts, stoppers) + if (!first) return null + if (ts.peekName() !== 'PUNC_COMMA' || stoppers.has('PUNC_COMMA')) return first + const node = makeNode('comma_expression', first.span) + node.children.push(first) + while (ts.peekName() === 'PUNC_COMMA' && !stoppers.has('PUNC_COMMA')) { + takeTokenInto(ts, node) // ',' + const next = parseAssignment(ts, stoppers) + if (!next) break + node.children.push(next) + } + return node +} + +// Assignment: right-associative; one of the assignment operators. +function parseAssignment(ts: TokenStream, stoppers: Set): CNode | null { + const left = parseConditional(ts, stoppers) + if (!left) return null + const opName = ts.peekName() + if (opName && ASSIGN_OPS.has(opName)) { + const node = makeNode('assignment_expression', left.span) + node.children.push(left) + node.left = left + const opTkn = takeTokenInto(ts, node)! + node.op = opTkn.src + const right = parseAssignment(ts, stoppers) // right-assoc + if (right) { + node.children.push(right) + node.right = right + } + return node + } + return left +} + +// Conditional / ternary: right-associative. +function parseConditional(ts: TokenStream, stoppers: Set): CNode | null { + const cond = parseBinary(ts, stoppers, 0) + if (!cond) return null + if (ts.peekName() !== 'PUNC_QUESTION') return cond + const node = makeNode('conditional_expression', cond.span) + node.children.push(cond) + node.cond = cond + takeTokenInto(ts, node) // '?' + // Middle: full expression up to ':'. + const then = parseExpression(ts, new Set([...stoppers, 'PUNC_COLON'])) + if (then) { + node.children.push(then) + node.then = then + } + if (ts.peekName() === 'PUNC_COLON') takeTokenInto(ts, node) + const els = parseAssignment(ts, stoppers) + if (els) { + node.children.push(els) + node.else = els + } + return node +} + +// Binary operators with precedence. `minPrec` is the lowest precedence +// we'll keep absorbing. +function parseBinary( + ts: TokenStream, stoppers: Set, minPrec: number, +): CNode | null { + let left = parseUnary(ts, stoppers) + if (!left) return null + while (true) { + const n = ts.peekName() + if (!n || stoppers.has(n)) break + const op = BINARY_OPS[n] + if (!op || op.prec < minPrec) break + const node = makeNode('binary_expression', left.span) + node.children.push(left) + node.left = left + const opTkn = takeTokenInto(ts, node)! + node.op = opTkn.src + const right = parseBinary(ts, stoppers, op.prec + 1) + if (!right) { + // Recovery: bail out of the loop. The incomplete node is still + // useful for downstream consumers. + break + } + node.children.push(right) + node.right = right + left = node + } + return left +} + +// Prefix unary operators, including sizeof/_Alignof/typeof in their +// expression forms. Recurses into the operand. +function parseUnary(ts: TokenStream, stoppers: Set): CNode | null { + const n = ts.peekName() + if (n && PREFIX_OPS.has(n)) { + const startTkn = ts.peek()! + const node = makeNode('unary_expression', spanOf(startTkn)) + const opTkn = takeTokenInto(ts, node)! + node.op = opTkn.src + // sizeof / _Alignof can take a parenthesised type-name, not an + // expression. We detect by peeking: `sizeof ( ...` is a type-form. + if ((n === 'KW_SIZEOF' || n === 'KW__ALIGNOF' || n === 'KW_ALIGNOF' || + n === 'KW___ALIGNOF__' || n === 'KW___ALIGNOF') && + ts.peekName() === 'PUNC_LPAREN' && + looksLikeTypeName(ts, 1)) { + const tn = makeNode('type_name', spanOf(ts.peek()!)) + consumeBalanced(ts, tn, 'PUNC_LPAREN', 'PUNC_RPAREN') + node.children.push(tn) + node.operand = tn + return node + } + const operand = parseUnary(ts, stoppers) + if (operand) { + node.children.push(operand) + node.operand = operand + } + return node + } + return parsePostfix(ts, stoppers) +} + +// Postfix loop: subscript, call, member access, increment/decrement. +function parsePostfix(ts: TokenStream, stoppers: Set): CNode | null { + let target = parsePrimary(ts, stoppers) + if (!target) return null + while (true) { + const n = ts.peekName() + if (!n || stoppers.has(n)) break + if (n === 'PUNC_LBRACKET') { + const node = makeNode('subscript_expression', target.span) + node.children.push(target) + node.target = target + const idx = makeNode('index_list', spanOf(ts.peek()!)) + consumeBalanced(ts, idx, 'PUNC_LBRACKET', 'PUNC_RBRACKET') + node.children.push(idx) + target = node + continue + } + if (n === 'PUNC_LPAREN') { + const node = makeNode('call_expression', target.span) + node.children.push(target) + // Tag isMacro when the immediate target is an identifier_expression + // whose token was MACRO_NAME. + const callee = unwrapCallee(target) + if (callee) { + node.callee = callee.src + node.isMacro = callee.tname === 'MACRO_NAME' + } + const args = makeNode('argument_list', spanOf(ts.peek()!)) + // Parse comma-separated assignment-expressions as arguments. + takeTokenInto(ts, args) // '(' + while (!ts.done() && ts.peekName() !== 'PUNC_RPAREN') { + const a = parseAssignment(ts, new Set(['PUNC_COMMA', 'PUNC_RPAREN'])) + if (a) args.children.push(a) + else { + // Defensive: avoid infinite loop on something we don't grok. + takeTokenInto(ts, args) + } + if (ts.peekName() === 'PUNC_COMMA') takeTokenInto(ts, args) + } + if (ts.peekName() === 'PUNC_RPAREN') takeTokenInto(ts, args) + node.children.push(args) + target = node + continue + } + if (n === 'PUNC_DOT' || n === 'PUNC_ARROW') { + const node = makeNode('member_expression', target.span) + node.children.push(target) + node.object = target + const opTkn = takeTokenInto(ts, node)! + node.op = opTkn.src + // The member name is the next ID (or possibly a TYPEDEF_NAME, in + // exceptional code). + const memTkn = ts.peek() + if (memTkn && (memTkn.name === 'ID' || memTkn.name === 'TYPEDEF_NAME' || + memTkn.name === 'MACRO_NAME')) { + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.memberName = taken.tkn.src + } + target = node + continue + } + if (POSTFIX_OPS.has(n)) { + const node = makeNode('postfix_unary_expression', target.span) + node.children.push(target) + node.target = target + const opTkn = takeTokenInto(ts, node)! + node.op = opTkn.src + target = node + continue + } + break + } + return target +} + +function unwrapCallee(node: CNode): CTokenRef | null { + if (node.kind !== 'identifier_expression') return null + const t = node.children.find((c: any) => c.kind === 'token') + return (t as CTokenRef) || null +} + +// Primary: literal, identifier, parenthesised, generic, statement-expr, +// compound literal. +function parsePrimary(ts: TokenStream, stoppers: Set): CNode | null { + const t = ts.peek() + if (!t) return null + const n = t.name + if (n === 'LIT_INT' || n === 'LIT_FLOAT' || + n === 'LIT_CHAR' || n === 'LIT_STRING') { + const node = makeNode('literal_expression', spanOf(t)) + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.literalKind = n + node.value = taken.tkn.src + // Adjacent string literals concatenate ("foo" "bar") — keep all in + // one literal_expression node. + if (n === 'LIT_STRING') { + while (ts.peekName() === 'LIT_STRING') { + const more = ts.take()! + for (const tr of more.trivia) node.children.push(tr) + node.children.push(more.ref) + } + } + return node + } + if (n === 'ID' || n === 'MACRO_NAME' || n === 'TYPEDEF_NAME') { + const node = makeNode('identifier_expression', spanOf(t)) + const taken = ts.take()! + for (const tr of taken.trivia) node.children.push(tr) + node.children.push(taken.ref) + node.name = taken.tkn.src + return node + } + if (n === 'KW__GENERIC') { + const node = makeNode('generic_selection', spanOf(t)) + takeTokenInto(ts, node) + if (ts.peekName() === 'PUNC_LPAREN') { + consumeBalanced(ts, node, 'PUNC_LPAREN', 'PUNC_RPAREN') + } + return node + } + if (n === 'PUNC_LPAREN') { + // GCC statement-expression `({ ... })`. + if (ts.peekName(1) === 'PUNC_LBRACE') { + const node = makeNode('statement_expression', spanOf(t)) + consumeBalanced(ts, node, 'PUNC_LPAREN', 'PUNC_RPAREN') + return node + } + // Cast vs parenthesised expression vs compound literal: peek ahead + // one token. If it begins a type-name, the form is `( type-name ) X` + // (cast) or `( type-name ) { … }` (compound literal). + if (looksLikeTypeName(ts, 1)) { + // Find the closing ) and check what follows. + const m = ts.mark() + const opener = ts.take()! // '(' + const tn = makeNode('type_name', spanOf(opener.tkn)) + // Take the `(` we already consumed back as a child token. + tn.children.push(opener.ref) + // Consume balanced contents up to and including the matching ')' + // (we treat the type-name's body as opaque tokens for now). + let depth = 1 + while (!ts.done() && depth > 0) { + const nn = ts.peekName() + if (nn === 'PUNC_LPAREN') depth++ + else if (nn === 'PUNC_RPAREN') { + depth-- + if (depth === 0) { + takeTokenInto(ts, tn) // closing ')' + break + } + } + takeTokenInto(ts, tn) + } + // Compound literal: followed by `{`. + if (ts.peekName() === 'PUNC_LBRACE') { + const cl = makeNode('compound_literal', tn.span) + cl.children.push(tn) + cl.typeName = tn + const init = makeNode('initializer_list', spanOf(ts.peek()!)) + consumeBalanced(ts, init, 'PUNC_LBRACE', 'PUNC_RBRACE') + cl.children.push(init) + return cl + } + // Cast: followed by an expression. + const operand = parseUnary(ts, stoppers) + if (operand) { + const cast = makeNode('cast_expression', tn.span) + cast.children.push(tn) + cast.children.push(operand) + cast.typeName = tn + cast.operand = operand + return cast + } + // Couldn't parse as cast — restore and fall through to plain + // parenthesised expression. + ts.restore(m) + } + // Plain parenthesised expression. + const node = makeNode('paren_expression', spanOf(t)) + takeTokenInto(ts, node) // '(' + const inner = parseExpression(ts, new Set(['PUNC_RPAREN'])) + if (inner) node.children.push(inner) + if (ts.peekName() === 'PUNC_RPAREN') takeTokenInto(ts, node) + return node + } + return null +} + +// Lookahead helper: does the token at offset `off` begin a type-name? +// True for type keywords and TYPEDEF_NAMEs. (Enough for the common +// cast / sizeof / compound-literal cases; full type-name detection is +// more involved and lives in structure.ts's specifier path.) +function looksLikeTypeName(ts: TokenStream, off: number): boolean { + const t = ts.peek(off) + if (!t) return false + if (t.name === 'TYPEDEF_NAME') return true + if (TYPE_KEYWORDS.has(t.name)) return true + return false +} + +function consumeBalanced( + ts: TokenStream, node: CNode, open: string, close: string, +): boolean { + if (ts.peekName() !== open) return false + takeTokenInto(ts, node) + let depth = 1 + while (depth > 0 && !ts.done()) { + const n = ts.peekName() + if (n === open) depth++ + else if (n === close) depth-- + takeTokenInto(ts, node) + } + return depth === 0 +} diff --git a/src/structure.ts b/src/structure.ts index 3ea5e68..a5e4749 100644 --- a/src/structure.ts +++ b/src/structure.ts @@ -17,6 +17,7 @@ // composable function. import type { Token } from 'jsonic' +import { parseExpression } from './expr.js' export interface Span { start: number; end: number; line: number; col: number @@ -898,35 +899,24 @@ function structureCallsInPlace(node: CNode): void { node.children = out } -// Initializer is opaque-balanced for now: a single token, or a brace -// group, or anything until a top-level `,` or `;` or `}`. +// Initializer: assignment-expression OR brace-enclosed initializer-list. export function parseInitializer(ts: TokenStream): CNode | null { const startTkn = ts.peek() if (!startTkn) return null const node = makeNode('initializer', spanOf(startTkn)) if (ts.peekName() === 'PUNC_LBRACE') { + // For now keep the initializer-list opaque-balanced; designated + // initializers (`.x = 1`, `[2] = 3`) need their own structuring + // pass which is left for a later slice. consumeBalanced(ts, node, 'PUNC_LBRACE', 'PUNC_RBRACE') return node } - // Otherwise, absorb up to the first top-level `,` `;` or `}`. - let parenD = 0, bracketD = 0 - while (!ts.done()) { - const n = ts.peekName() - if (n === 'PUNC_LPAREN') { parenD++; ts.takeInto(node); continue } - if (n === 'PUNC_RPAREN') { - if (parenD === 0) break - parenD--; ts.takeInto(node); continue - } - if (n === 'PUNC_LBRACKET') { bracketD++; ts.takeInto(node); continue } - if (n === 'PUNC_RBRACKET') { - if (bracketD === 0) break - bracketD--; ts.takeInto(node); continue - } - if (parenD === 0 && bracketD === 0 && - (n === 'PUNC_COMMA' || n === 'PUNC_SEMI' || n === 'PUNC_RBRACE')) break - ts.takeInto(node) - } - structureCallsInPlace(node) + // Plain expression initializer — assignment-precedence (no top-level + // comma). + const expr = parseExpression( + ts, new Set(['PUNC_COMMA', 'PUNC_SEMI', 'PUNC_RBRACE']), + ) + if (expr) node.children.push(expr) return node } @@ -1132,12 +1122,14 @@ function parseJumpStatement(ts: TokenStream): CNode { const node = makeNode('jump_statement', spanOf(startTkn)) node.jumpKind = startTkn.src ts.takeInto(node) // jump keyword - // Consume tokens up to the terminating `;`. - while (!ts.done() && ts.peekName() !== 'PUNC_SEMI') { - ts.takeInto(node) + // For `return ;` and `goto